如何为包括管道的代码制作循环
How to make a loop for code including pipes
我是 R 代码的新手,我试图避免复制粘贴同一行 20 次,因为我目前正在尝试手动执行此操作:
我有一个包含 3 个变量的数据框:date.time、深度、毫秒(示例):
date.time Depth ms
1: 2015-12-20 00:48:50 113.5 0.316666667
2: 2015-12-20 01:25:50 156.0 -0.966666667
3: 2015-12-20 01:26:50 170.5 -0.241666667
4: 2015-12-20 01:27:50 215.5 -0.750000000
5: 2015-12-20 01:28:50 276.5 -1.016666667
6: 2015-12-20 01:29:50 373.0 -1.608333333
7: 2015-12-20 01:30:50 453.0 -1.333333333
8: 2015-12-20 01:31:50 500.0 -0.783333333
9: 2015-12-20 01:35:50 512.0 0.241666667
10: 2015-12-20 03:53:50 285.0 0.058333333
11: 2015-12-20 03:54:50 355.0 -1.166666667
12: 2015-12-20 03:55:50 453.5 -1.641666667
12: 2015-12-20 03:57:50 526.0 0.000000000
14: 2015-12-21 15:01:50 449.5 0.016666667
15: 2015-12-21 15:02:50 467.5 -0.300000000
16: 2015-12-21 16:07:50 308.5 0.100000000
17: 2015-12-21 16:08:50 392.0 -1.391666667
18: 2015-12-21 16:09:50 491.0 -1.650000000
19: 2015-12-21 16:11:50 581.0 0.000000000
20: 2015-12-22 22:02:50 461.0 0.075000000
21: 2015-12-22 22:03:50 463.0 -0.033333333
22: 2015-12-22 22:04:50 466.0 -0.050000000
23: 2015-12-22 22:05:50 467.5 -0.025000000
24: 2015-12-22 22:06:50 468.0 -0.008333333
25: 2015-12-22 22:07:50 471.0 -0.050000000
26: 2015-12-22 22:08:50 472.5 -0.025000000
27: 2015-12-22 22:09:50 530.0 -0.958333333
我通过选择潜水开始和结束的行来手动完成此操作以分隔每次潜水(例如:
d1<- df[c(1:9),]
d2<- df[c(10:13),]
d3<- df[c(14:20),]
d4<- df[c(21:27),]
然后将以下代码应用于我正在创建的每个新 df (d1、d2、d3、d4)(下面是 d1 的示例):
d1<- newdf[c(1:19),]
d1$date.time <- as_datetime(d1$date.time)
str(d1)
d1 %>%
group_by(Ptt) %>%
mutate(
diffMin = difftime(date.time, lag(date.time,1, default = date.time[1] ), unit = "mins") %>% #calculate time diff of each row
as.numeric() %>% #changes to numeric
cumsum() #gets cumulative sum
) -> d1
d1$Divenumber <- as.character('1')
这给了我想要的输出:
d1
date.time Depth ms diffMin Divenumber
<dttm> <dbl> <dbl> <dbl> <chr>
1 2015-12-20 00:48:50 114. 0.317 0 1
2 2015-12-20 01:25:50 156 -0.967 37 1
3 2015-12-20 01:26:50 170. -0.242 38 1
4 2015-12-20 01:27:50 216. -0.75 39 1
5 2015-12-20 01:28:50 276. -1.02 40 1
6 2015-12-20 01:29:50 373 -1.61 41 1
7 2015-12-20 01:30:50 453 -1.33 42 1
8 2015-12-20 01:31:50 500 -0.783 43 1
9 2015-12-20 01:35:50 512 0.242 47 1
d2
date.time Depth ms diffMin Divenumber
<dttm> <dbl> <dbl> <dbl> <chr>
1 2015-12-20 03:53:50 285 0.0583 0 2
2 2015-12-20 03:54:50 355 -1.17 1 2
3 2015-12-20 03:55:50 454. -1.64 2 2
4 2015-12-20 03:57:50 526 0 4 2
对于每个新的 df,但如您所见,为了获取每个新的 df 然后在最后绑定它们,需要进行大量的复制粘贴。我确信有一种更快的方法可以做到这一点,但经过几个小时的尝试后无法完全正确。有人可以帮我做这个(也许在某种类型的循环中)这将使我能够遍历整个数据集并为每个新潜水分配一个新的潜水编号以及从该潜水开始的时间差和几分钟后结束潜水?另外,将来不必手动分离潜水会很棒,只能考虑使用 case_when
lag
和 date.time
创建某种类型的代码来区分潜水。但很高兴有任何其他可能的建议!
这是我的一部分数据的输入:
structure(list(date.time = structure(c(1450572530, 1450574750,
1450574810, 1450574870, 1450574930, 1450574990, 1450575050, 1450575110,
1450575350, 1450583630, 1450583690, 1450583750, 1450583870,
1450710110, 1450710170, 1450714070, 1450714130, 1450714190, 1450714310,
1450821770, 1450821830, 1450821890, 1450821950, 1450822010, 1450822070,
1450822130, 1450822190), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
Depth = c(113.5, 156, 170.5, 215.5, 276.5, 373, 453, 500,
512, 285, 355, 453.5, 526, 449.5, 467.5, 308.5, 392,
491, 581, 461, 463, 466, 467.5, 468, 471, 472.5, 530), ms = c(0.316666666666667,
-0.966666666666667, -0.241666666666667, -0.75, -1.01666666666667,
-1.60833333333333, -1.33333333333333, -0.783333333333333,
0.241666666666667, 0.0583333333333333,
-1.16666666666667, -1.64166666666667, 0, 0.0166666666666667,
-0.3, 0.1, -1.39166666666667, -1.65, 0, 0.075, -0.0333333333333333,
-0.05, -0.025, -0.00833333333333333, -0.05, -0.025, -0.958333333333333
)), row.names = c(NA, -28L), class = c("data.table", "data.frame"
)
提前致谢
将阈值保持为 2 小时,您可以使用 cumsum
as -
自动创建 dive
列
library(dplyr)
n_seconds <- 7200 #2hours
df <- df %>%
mutate(dive = cumsum(difftime(date.time,
lag(date.time, default = first(date.time) - n_seconds - 1),
units = 'secs') > n_seconds))
df
# date.time Depth ms dive
#1 2015-12-20 00:48:50 113.5 0.316666667 1
#2 2015-12-20 01:25:50 156.0 -0.966666667 1
#3 2015-12-20 01:26:50 170.5 -0.241666667 1
#4 2015-12-20 01:27:50 215.5 -0.750000000 1
#5 2015-12-20 01:28:50 276.5 -1.016666667 1
#6 2015-12-20 01:29:50 373.0 -1.608333333 1
#7 2015-12-20 01:30:50 453.0 -1.333333333 1
#8 2015-12-20 01:31:50 500.0 -0.783333333 1
#9 2015-12-20 01:35:50 512.0 0.241666667 1
#10 2015-12-20 03:53:50 285.0 0.058333333 2
#11 2015-12-20 03:54:50 355.0 -1.166666667 2
#12 2015-12-20 03:55:50 453.5 -1.641666667 2
#13 2015-12-20 03:57:50 526.0 0.000000000 2
#14 2015-12-21 15:01:50 449.5 0.016666667 3
#15 2015-12-21 15:02:50 467.5 -0.300000000 3
#16 2015-12-21 16:07:50 308.5 0.100000000 3
#17 2015-12-21 16:08:50 392.0 -1.391666667 3
#18 2015-12-21 16:09:50 491.0 -1.650000000 3
#19 2015-12-21 16:11:50 581.0 0.000000000 3
#20 2015-12-22 22:02:50 461.0 0.075000000 4
#21 2015-12-22 22:03:50 463.0 -0.033333333 4
#22 2015-12-22 22:04:50 466.0 -0.050000000 4
#23 2015-12-22 22:05:50 467.5 -0.025000000 4
#24 2015-12-22 22:06:50 468.0 -0.008333333 4
#25 2015-12-22 22:07:50 471.0 -0.050000000 4
#26 2015-12-22 22:08:50 472.5 -0.025000000 4
#27 2015-12-22 22:09:50 530.0 -0.958333333 4
您可以根据您的数据适当更改阈值,我根据提供的示例选择了 2 小时。
一种不同的方法。我使用了一个简单的 while 循环来完成您的要求。并使用了你在评论中所说的潜水逻辑。如果您有任何疑问,请告诉我。
#Load the data in df
#Create a list for the dive. Set the first element as 1, as it will be dive 1
dive <- c(1)
#Create a counter
dive_count <- 1
#Start the while loop from i =2, as the first one is automatically considered in dive 1
i <-2
while (i <= nrow(df)) {
if (df$Depth[i]> df$Depth[i-1]){
dive[i] <- dive_count
}
else{
dive_count <- dive_count+1
dive[i] <- dive_count
}
i<- i+1
}
df$dive <- dive
检查最终数据框
df
date.time Depth ms dive
1 2015-12-20 00:48:50 113.5 0.316666667 1
2 2015-12-20 01:25:50 156.0 -0.966666667 1
3 2015-12-20 01:26:50 170.5 -0.241666667 1
4 2015-12-20 01:27:50 215.5 -0.750000000 1
5 2015-12-20 01:28:50 276.5 -1.016666667 1
6 2015-12-20 01:29:50 373.0 -1.608333333 1
7 2015-12-20 01:30:50 453.0 -1.333333333 1
8 2015-12-20 01:31:50 500.0 -0.783333333 1
9 2015-12-20 01:35:50 512.0 0.241666667 1
10 2015-12-20 03:53:50 285.0 0.058333333 2
11 2015-12-20 03:54:50 355.0 -1.166666667 2
12 2015-12-20 03:55:50 453.5 -1.641666667 2
13 2015-12-20 03:57:50 526.0 0.000000000 2
14 2015-12-21 15:01:50 449.5 0.016666667 3
15 2015-12-21 15:02:50 467.5 -0.300000000 3
16 2015-12-21 16:07:50 308.5 0.100000000 4
17 2015-12-21 16:08:50 392.0 -1.391666667 4
18 2015-12-21 16:09:50 491.0 -1.650000000 4
19 2015-12-21 16:11:50 581.0 0.000000000 4
20 2015-12-22 22:02:50 461.0 0.075000000 5
21 2015-12-22 22:03:50 463.0 -0.033333333 5
22 2015-12-22 22:04:50 466.0 -0.050000000 5
23 2015-12-22 22:05:50 467.5 -0.025000000 5
24 2015-12-22 22:06:50 468.0 -0.008333333 5
25 2015-12-22 22:07:50 471.0 -0.050000000 5
26 2015-12-22 22:08:50 472.5 -0.025000000 5
27 2015-12-22 22:09:50 530.0 -0.958333333 5
执行以上由 Ronak 发布的代码,然后使用管道按潜水分组并计算累计潜水时间:
df <- df %>%
group_by(dive) %>%
mutate(
diffMin = difftime(date.time, lag(date.time,1, default = date.time[1] ), unit = "mins") %>% #calculate time diff of each row
as.numeric() %>% #changes to numeric
cumsum()) #gets cumulative sum
我是 R 代码的新手,我试图避免复制粘贴同一行 20 次,因为我目前正在尝试手动执行此操作: 我有一个包含 3 个变量的数据框:date.time、深度、毫秒(示例):
date.time Depth ms
1: 2015-12-20 00:48:50 113.5 0.316666667
2: 2015-12-20 01:25:50 156.0 -0.966666667
3: 2015-12-20 01:26:50 170.5 -0.241666667
4: 2015-12-20 01:27:50 215.5 -0.750000000
5: 2015-12-20 01:28:50 276.5 -1.016666667
6: 2015-12-20 01:29:50 373.0 -1.608333333
7: 2015-12-20 01:30:50 453.0 -1.333333333
8: 2015-12-20 01:31:50 500.0 -0.783333333
9: 2015-12-20 01:35:50 512.0 0.241666667
10: 2015-12-20 03:53:50 285.0 0.058333333
11: 2015-12-20 03:54:50 355.0 -1.166666667
12: 2015-12-20 03:55:50 453.5 -1.641666667
12: 2015-12-20 03:57:50 526.0 0.000000000
14: 2015-12-21 15:01:50 449.5 0.016666667
15: 2015-12-21 15:02:50 467.5 -0.300000000
16: 2015-12-21 16:07:50 308.5 0.100000000
17: 2015-12-21 16:08:50 392.0 -1.391666667
18: 2015-12-21 16:09:50 491.0 -1.650000000
19: 2015-12-21 16:11:50 581.0 0.000000000
20: 2015-12-22 22:02:50 461.0 0.075000000
21: 2015-12-22 22:03:50 463.0 -0.033333333
22: 2015-12-22 22:04:50 466.0 -0.050000000
23: 2015-12-22 22:05:50 467.5 -0.025000000
24: 2015-12-22 22:06:50 468.0 -0.008333333
25: 2015-12-22 22:07:50 471.0 -0.050000000
26: 2015-12-22 22:08:50 472.5 -0.025000000
27: 2015-12-22 22:09:50 530.0 -0.958333333
我通过选择潜水开始和结束的行来手动完成此操作以分隔每次潜水(例如:
d1<- df[c(1:9),]
d2<- df[c(10:13),]
d3<- df[c(14:20),]
d4<- df[c(21:27),]
然后将以下代码应用于我正在创建的每个新 df (d1、d2、d3、d4)(下面是 d1 的示例):
d1<- newdf[c(1:19),]
d1$date.time <- as_datetime(d1$date.time)
str(d1)
d1 %>%
group_by(Ptt) %>%
mutate(
diffMin = difftime(date.time, lag(date.time,1, default = date.time[1] ), unit = "mins") %>% #calculate time diff of each row
as.numeric() %>% #changes to numeric
cumsum() #gets cumulative sum
) -> d1
d1$Divenumber <- as.character('1')
这给了我想要的输出:
d1
date.time Depth ms diffMin Divenumber
<dttm> <dbl> <dbl> <dbl> <chr>
1 2015-12-20 00:48:50 114. 0.317 0 1
2 2015-12-20 01:25:50 156 -0.967 37 1
3 2015-12-20 01:26:50 170. -0.242 38 1
4 2015-12-20 01:27:50 216. -0.75 39 1
5 2015-12-20 01:28:50 276. -1.02 40 1
6 2015-12-20 01:29:50 373 -1.61 41 1
7 2015-12-20 01:30:50 453 -1.33 42 1
8 2015-12-20 01:31:50 500 -0.783 43 1
9 2015-12-20 01:35:50 512 0.242 47 1
d2
date.time Depth ms diffMin Divenumber
<dttm> <dbl> <dbl> <dbl> <chr>
1 2015-12-20 03:53:50 285 0.0583 0 2
2 2015-12-20 03:54:50 355 -1.17 1 2
3 2015-12-20 03:55:50 454. -1.64 2 2
4 2015-12-20 03:57:50 526 0 4 2
对于每个新的 df,但如您所见,为了获取每个新的 df 然后在最后绑定它们,需要进行大量的复制粘贴。我确信有一种更快的方法可以做到这一点,但经过几个小时的尝试后无法完全正确。有人可以帮我做这个(也许在某种类型的循环中)这将使我能够遍历整个数据集并为每个新潜水分配一个新的潜水编号以及从该潜水开始的时间差和几分钟后结束潜水?另外,将来不必手动分离潜水会很棒,只能考虑使用 case_when
lag
和 date.time
创建某种类型的代码来区分潜水。但很高兴有任何其他可能的建议!
这是我的一部分数据的输入:
structure(list(date.time = structure(c(1450572530, 1450574750,
1450574810, 1450574870, 1450574930, 1450574990, 1450575050, 1450575110,
1450575350, 1450583630, 1450583690, 1450583750, 1450583870,
1450710110, 1450710170, 1450714070, 1450714130, 1450714190, 1450714310,
1450821770, 1450821830, 1450821890, 1450821950, 1450822010, 1450822070,
1450822130, 1450822190), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
Depth = c(113.5, 156, 170.5, 215.5, 276.5, 373, 453, 500,
512, 285, 355, 453.5, 526, 449.5, 467.5, 308.5, 392,
491, 581, 461, 463, 466, 467.5, 468, 471, 472.5, 530), ms = c(0.316666666666667,
-0.966666666666667, -0.241666666666667, -0.75, -1.01666666666667,
-1.60833333333333, -1.33333333333333, -0.783333333333333,
0.241666666666667, 0.0583333333333333,
-1.16666666666667, -1.64166666666667, 0, 0.0166666666666667,
-0.3, 0.1, -1.39166666666667, -1.65, 0, 0.075, -0.0333333333333333,
-0.05, -0.025, -0.00833333333333333, -0.05, -0.025, -0.958333333333333
)), row.names = c(NA, -28L), class = c("data.table", "data.frame"
)
提前致谢
将阈值保持为 2 小时,您可以使用 cumsum
as -
dive
列
library(dplyr)
n_seconds <- 7200 #2hours
df <- df %>%
mutate(dive = cumsum(difftime(date.time,
lag(date.time, default = first(date.time) - n_seconds - 1),
units = 'secs') > n_seconds))
df
# date.time Depth ms dive
#1 2015-12-20 00:48:50 113.5 0.316666667 1
#2 2015-12-20 01:25:50 156.0 -0.966666667 1
#3 2015-12-20 01:26:50 170.5 -0.241666667 1
#4 2015-12-20 01:27:50 215.5 -0.750000000 1
#5 2015-12-20 01:28:50 276.5 -1.016666667 1
#6 2015-12-20 01:29:50 373.0 -1.608333333 1
#7 2015-12-20 01:30:50 453.0 -1.333333333 1
#8 2015-12-20 01:31:50 500.0 -0.783333333 1
#9 2015-12-20 01:35:50 512.0 0.241666667 1
#10 2015-12-20 03:53:50 285.0 0.058333333 2
#11 2015-12-20 03:54:50 355.0 -1.166666667 2
#12 2015-12-20 03:55:50 453.5 -1.641666667 2
#13 2015-12-20 03:57:50 526.0 0.000000000 2
#14 2015-12-21 15:01:50 449.5 0.016666667 3
#15 2015-12-21 15:02:50 467.5 -0.300000000 3
#16 2015-12-21 16:07:50 308.5 0.100000000 3
#17 2015-12-21 16:08:50 392.0 -1.391666667 3
#18 2015-12-21 16:09:50 491.0 -1.650000000 3
#19 2015-12-21 16:11:50 581.0 0.000000000 3
#20 2015-12-22 22:02:50 461.0 0.075000000 4
#21 2015-12-22 22:03:50 463.0 -0.033333333 4
#22 2015-12-22 22:04:50 466.0 -0.050000000 4
#23 2015-12-22 22:05:50 467.5 -0.025000000 4
#24 2015-12-22 22:06:50 468.0 -0.008333333 4
#25 2015-12-22 22:07:50 471.0 -0.050000000 4
#26 2015-12-22 22:08:50 472.5 -0.025000000 4
#27 2015-12-22 22:09:50 530.0 -0.958333333 4
您可以根据您的数据适当更改阈值,我根据提供的示例选择了 2 小时。
一种不同的方法。我使用了一个简单的 while 循环来完成您的要求。并使用了你在评论中所说的潜水逻辑。如果您有任何疑问,请告诉我。
#Load the data in df
#Create a list for the dive. Set the first element as 1, as it will be dive 1
dive <- c(1)
#Create a counter
dive_count <- 1
#Start the while loop from i =2, as the first one is automatically considered in dive 1
i <-2
while (i <= nrow(df)) {
if (df$Depth[i]> df$Depth[i-1]){
dive[i] <- dive_count
}
else{
dive_count <- dive_count+1
dive[i] <- dive_count
}
i<- i+1
}
df$dive <- dive
检查最终数据框
df
date.time Depth ms dive
1 2015-12-20 00:48:50 113.5 0.316666667 1
2 2015-12-20 01:25:50 156.0 -0.966666667 1
3 2015-12-20 01:26:50 170.5 -0.241666667 1
4 2015-12-20 01:27:50 215.5 -0.750000000 1
5 2015-12-20 01:28:50 276.5 -1.016666667 1
6 2015-12-20 01:29:50 373.0 -1.608333333 1
7 2015-12-20 01:30:50 453.0 -1.333333333 1
8 2015-12-20 01:31:50 500.0 -0.783333333 1
9 2015-12-20 01:35:50 512.0 0.241666667 1
10 2015-12-20 03:53:50 285.0 0.058333333 2
11 2015-12-20 03:54:50 355.0 -1.166666667 2
12 2015-12-20 03:55:50 453.5 -1.641666667 2
13 2015-12-20 03:57:50 526.0 0.000000000 2
14 2015-12-21 15:01:50 449.5 0.016666667 3
15 2015-12-21 15:02:50 467.5 -0.300000000 3
16 2015-12-21 16:07:50 308.5 0.100000000 4
17 2015-12-21 16:08:50 392.0 -1.391666667 4
18 2015-12-21 16:09:50 491.0 -1.650000000 4
19 2015-12-21 16:11:50 581.0 0.000000000 4
20 2015-12-22 22:02:50 461.0 0.075000000 5
21 2015-12-22 22:03:50 463.0 -0.033333333 5
22 2015-12-22 22:04:50 466.0 -0.050000000 5
23 2015-12-22 22:05:50 467.5 -0.025000000 5
24 2015-12-22 22:06:50 468.0 -0.008333333 5
25 2015-12-22 22:07:50 471.0 -0.050000000 5
26 2015-12-22 22:08:50 472.5 -0.025000000 5
27 2015-12-22 22:09:50 530.0 -0.958333333 5
执行以上由 Ronak 发布的代码,然后使用管道按潜水分组并计算累计潜水时间:
df <- df %>%
group_by(dive) %>%
mutate(
diffMin = difftime(date.time, lag(date.time,1, default = date.time[1] ), unit = "mins") %>% #calculate time diff of each row
as.numeric() %>% #changes to numeric
cumsum()) #gets cumulative sum