如何使用两个索引创建一个 for 循环?
How to make a for loop with two indexes?
尊敬的 Whosebug 用户,
我正在努力实现 for 循环。我有一个带有时间列(YMD-HMS 格式)的数据框和另一个带有颗粒物数据的列。此外,我有一个包含开始和停止时刻的数据框;
#TIMEPOINTS log
start <- c(ymd_hms("2020-03-06 19:43:00",
"2020-03-06 19:47:00",
"2020-03-06 19:53:00",
"2020-03-06 20:00:00",
"2020-03-06 20:13:00",
"2020-03-06 20:22:00",
"2020-03-06 20:32:00",
"2020-03-06 20:36:00",
"2020-03-06 20:42:00",
"2020-03-06 20:45:00",
"2020-03-06 20:49:00",
"2020-03-06 21:01:00",
"2020-03-06 21:04:00",
"2020-03-06 21:06:00",
"2020-03-06 21:09:00",
"2020-03-06 21:12:00"))
end <- c(ymd_hms("2020-03-06 19:46:00",
"2020-03-06 19:49:00",
"2020-03-06 19:55:00",
"2020-03-06 20:02:00",
"2020-03-06 20:15:00",
"2020-03-06 20:24:00",
"2020-03-06 20:34:00",
"2020-03-06 20:38:00",
"2020-03-06 20:44:00",
"2020-03-06 20:47:00",
"2020-03-06 20:51:00",
"2020-03-06 21:03:00",
"2020-03-06 21:06:00",
"2020-03-06 21:08:00",
"2020-03-06 21:11:00",
"2020-03-06 21:14:00"))
df <- data.frame(start, end)
我希望创建一个包含所有数据点但没有这些特定时间点的新数据框,如下所示; (但不是使用 forloop,迭代各种起点和终点)。
dat2 <- dat %>% .[.[["Time"]] >= df$start[1],] %>%
.[.[["Time"]] <= df$end[1],]
我知道这可以使用 for 循环来完成,我试图为我的情况弄清楚,但我有点迷路了..
非常感谢任何帮助!
首先,我会稍微清理一下您当前的代码:
dat2 <- dat %>% .[.$Time >= df$start[1] && .$Time <= df$end[1],]
通过使用 &&
,您已将两个子集操作缩减为一个。在这种情况下,与 [["…"]]
相比,使用 $…
可以减少混乱。
接下来,我建议将这个条件提取到一个函数中(事实上该函数已经存在于‘dplyr’包中:between
)。这允许我们将代码编写为
dat2 <- dat %>% filter(between(Time, df$start[1], df$end[1]))
现在我们要对其进行矢量化以检查是否与 any 区间重叠:
dat2 <- dat %>% filter(between_any(Time, df$start, df$end))
现在我们需要编写 between_any
函数。让我们从为 单个 查询值实现它开始:
between_any1 = function (x, left, right) {
any(x >= left & x <= right)
}
注意这里使用的是&
,而不是&&
;这是因为我们 向量化 而不是 left
和 right
,而 &
是 &&
的向量化版本。也就是说,4 >= (1 : 3) & 4 <= (3 : 5)
结果是 c(FALSE, TRUE, TRUE)
.
现在我们需要在 x
是一个向量时使它起作用。我们可以使用基本的 R 函数 Vectorize
,但我通常发现手动操作更好:
between_any = function (x, left, right) {
map_lgl(x, ~ any(.x >= left & .x <= right))
}
这使用了‘purrr’,但我们也可以使用 lapply
或 vapply
。
哦,听起来您想 过滤掉 次落入 df
范围内的次数,因此您需要反转 [=34] 的条件=]:
dat2 <- dat %>% filter(! between_any(Time, df$from, df$to))
尊敬的 Whosebug 用户,
我正在努力实现 for 循环。我有一个带有时间列(YMD-HMS 格式)的数据框和另一个带有颗粒物数据的列。此外,我有一个包含开始和停止时刻的数据框;
#TIMEPOINTS log
start <- c(ymd_hms("2020-03-06 19:43:00",
"2020-03-06 19:47:00",
"2020-03-06 19:53:00",
"2020-03-06 20:00:00",
"2020-03-06 20:13:00",
"2020-03-06 20:22:00",
"2020-03-06 20:32:00",
"2020-03-06 20:36:00",
"2020-03-06 20:42:00",
"2020-03-06 20:45:00",
"2020-03-06 20:49:00",
"2020-03-06 21:01:00",
"2020-03-06 21:04:00",
"2020-03-06 21:06:00",
"2020-03-06 21:09:00",
"2020-03-06 21:12:00"))
end <- c(ymd_hms("2020-03-06 19:46:00",
"2020-03-06 19:49:00",
"2020-03-06 19:55:00",
"2020-03-06 20:02:00",
"2020-03-06 20:15:00",
"2020-03-06 20:24:00",
"2020-03-06 20:34:00",
"2020-03-06 20:38:00",
"2020-03-06 20:44:00",
"2020-03-06 20:47:00",
"2020-03-06 20:51:00",
"2020-03-06 21:03:00",
"2020-03-06 21:06:00",
"2020-03-06 21:08:00",
"2020-03-06 21:11:00",
"2020-03-06 21:14:00"))
df <- data.frame(start, end)
我希望创建一个包含所有数据点但没有这些特定时间点的新数据框,如下所示; (但不是使用 forloop,迭代各种起点和终点)。
dat2 <- dat %>% .[.[["Time"]] >= df$start[1],] %>%
.[.[["Time"]] <= df$end[1],]
我知道这可以使用 for 循环来完成,我试图为我的情况弄清楚,但我有点迷路了..
非常感谢任何帮助!
首先,我会稍微清理一下您当前的代码:
dat2 <- dat %>% .[.$Time >= df$start[1] && .$Time <= df$end[1],]
通过使用 &&
,您已将两个子集操作缩减为一个。在这种情况下,与 [["…"]]
相比,使用 $…
可以减少混乱。
接下来,我建议将这个条件提取到一个函数中(事实上该函数已经存在于‘dplyr’包中:between
)。这允许我们将代码编写为
dat2 <- dat %>% filter(between(Time, df$start[1], df$end[1]))
现在我们要对其进行矢量化以检查是否与 any 区间重叠:
dat2 <- dat %>% filter(between_any(Time, df$start, df$end))
现在我们需要编写 between_any
函数。让我们从为 单个 查询值实现它开始:
between_any1 = function (x, left, right) {
any(x >= left & x <= right)
}
注意这里使用的是&
,而不是&&
;这是因为我们 向量化 而不是 left
和 right
,而 &
是 &&
的向量化版本。也就是说,4 >= (1 : 3) & 4 <= (3 : 5)
结果是 c(FALSE, TRUE, TRUE)
.
现在我们需要在 x
是一个向量时使它起作用。我们可以使用基本的 R 函数 Vectorize
,但我通常发现手动操作更好:
between_any = function (x, left, right) {
map_lgl(x, ~ any(.x >= left & .x <= right))
}
这使用了‘purrr’,但我们也可以使用 lapply
或 vapply
。
哦,听起来您想 过滤掉 次落入 df
范围内的次数,因此您需要反转 [=34] 的条件=]:
dat2 <- dat %>% filter(! between_any(Time, df$from, df$to))