连续求和 R 中的列,直到满足条件
Continual summation of a column in R until condition is met
我正在尽最大努力学习 R,这是我第一次 post 在这个论坛上。
我目前有一个包含填充向量“x”和未填充向量“计数器”的数据框,如下所示:
x <- c(NA,1,0,0,0,0,1,1,1,1,0,1)
df <- data.frame("x" = x, "counter" = 0)
x counter
1 NA 0
2 1 0
3 0 0
4 0 0
5 0 0
6 0 0
7 1 0
8 1 0
9 1 0
10 1 0
11 0 0
12 1 0
我在尝试编写将简单地填充计数器以便计数器对 x 中累积的连续 1 求和但在 x 为零时恢复为零的代码时遇到了异常困难的时间。因此,我希望计数器按照上面的例子计算如下:
x counter
1 NA NA
2 1 1
3 0 0
4 0 0
5 0 0
6 0 0
7 1 1
8 1 2
9 1 3
10 1 4
11 0 0
12 1 1
我尝试过使用 lag() 和 ifelse(),无论是否使用 for 循环,但似乎离可行的解决方案越来越远(虽然滞后让我接近,但这些数字并未计算为预期....我的 ifelse 和 for 循环最终以 NA_real_、NA 或 1 的长度为 1 的向量结束。我也考虑过 cumsum - 但不确定如何将范围限定为 1s - 并搜索并查看了类似的 posts,例如 ;但是,我仍然无法弄清楚我期望的是一项非常简单的任务。
诚然,我处于早期 R 学习曲线的低点,非常感谢社区中任何人可以提供的任何帮助和建设性反馈。谢谢。
您可以使用:
library(dplyr)
df %>%
group_by(x1 = cumsum(replace(x, is.na(x), 0) == 0)) %>%
mutate(counter = (row_number() - 1) * x) %>%
ungroup %>%
select(-x1)
# x counter
# <dbl> <dbl>
# 1 NA NA
# 2 1 1
# 3 0 0
# 4 0 0
# 5 0 0
# 6 0 0
# 7 1 1
# 8 1 2
# 9 1 3
#10 1 4
#11 0 0
#12 1 1
解释步骤 -
- 创建一个新列 (
x1
),将 x
中的 NA
替换为 0,每当 [=15] 时将组值递增 1(使用 cumsum
) =].
- 对于每组,用 0 减去行号,然后乘以
x
。此乘法是必要的,因为它有助于将 counter
保持为 0,其中 x = 0
和 counter
保持为 NA
,其中 x
为 NA
。
欢迎@cpanagakos。
在 dplyr::lag
中,不可能使用仍然不存在的列。
(它不能引用自己。)
https://www.reddit.com/r/rstats/comments/a34n6b/dplyr_use_previous_row_from_a_column_thats_being/
例如:
library(tidyverse)
df <- tibble("x" = c(NA, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1))
# error: lag cannot refer to a column that still doesn't exist
df %>%
mutate(counter = case_when(is.na(x) ~ coalesce(lag(counter), 0),
x == 0 ~ 0,
x == 1 ~ lag(counter) + 1))
#> Error: Problem with `mutate()` input `counter`.
#> x object 'counter' not found
#> i Input `counter` is `case_when(...)`.
因此,如果您有一个“重置”计数器的条件,则需要编写一个公式来在需要重置时更改组,然后引用 row_number,它将重新启动在组内 1(如@Ronald Shah 和其他人建议):
df %>%
group_by(x1 = cumsum(!coalesce(x, 0))) %>%
mutate(counter = row_number() - 1) %>%
ungroup()
#> # A tibble: 12 x 3
#> x x1 counter
#> <dbl> <int> <dbl>
#> 1 NA 1 NA
#> 2 1 1 1
#> 3 0 2 0
#> 4 0 3 0
#> 5 0 4 0
#> 6 0 5 0
#> 7 1 5 1
#> 8 1 5 2
#> 9 1 5 3
#> 10 1 5 4
#> 11 0 6 0
#> 12 1 6 1
这将是可以证明在 R 中使用 for 循环的少数情况之一:因为备选方案在概念上更难理解。
我正在尽最大努力学习 R,这是我第一次 post 在这个论坛上。
我目前有一个包含填充向量“x”和未填充向量“计数器”的数据框,如下所示:
x <- c(NA,1,0,0,0,0,1,1,1,1,0,1)
df <- data.frame("x" = x, "counter" = 0)
x counter
1 NA 0
2 1 0
3 0 0
4 0 0
5 0 0
6 0 0
7 1 0
8 1 0
9 1 0
10 1 0
11 0 0
12 1 0
我在尝试编写将简单地填充计数器以便计数器对 x 中累积的连续 1 求和但在 x 为零时恢复为零的代码时遇到了异常困难的时间。因此,我希望计数器按照上面的例子计算如下:
x counter
1 NA NA
2 1 1
3 0 0
4 0 0
5 0 0
6 0 0
7 1 1
8 1 2
9 1 3
10 1 4
11 0 0
12 1 1
我尝试过使用 lag() 和 ifelse(),无论是否使用 for 循环,但似乎离可行的解决方案越来越远(虽然滞后让我接近,但这些数字并未计算为预期....我的 ifelse 和 for 循环最终以 NA_real_、NA 或 1 的长度为 1 的向量结束。我也考虑过 cumsum - 但不确定如何将范围限定为 1s - 并搜索并查看了类似的 posts,例如
诚然,我处于早期 R 学习曲线的低点,非常感谢社区中任何人可以提供的任何帮助和建设性反馈。谢谢。
您可以使用:
library(dplyr)
df %>%
group_by(x1 = cumsum(replace(x, is.na(x), 0) == 0)) %>%
mutate(counter = (row_number() - 1) * x) %>%
ungroup %>%
select(-x1)
# x counter
# <dbl> <dbl>
# 1 NA NA
# 2 1 1
# 3 0 0
# 4 0 0
# 5 0 0
# 6 0 0
# 7 1 1
# 8 1 2
# 9 1 3
#10 1 4
#11 0 0
#12 1 1
解释步骤 -
- 创建一个新列 (
x1
),将x
中的NA
替换为 0,每当 [=15] 时将组值递增 1(使用cumsum
) =]. - 对于每组,用 0 减去行号,然后乘以
x
。此乘法是必要的,因为它有助于将counter
保持为 0,其中x = 0
和counter
保持为NA
,其中x
为NA
。
欢迎@cpanagakos。
在 dplyr::lag
中,不可能使用仍然不存在的列。
(它不能引用自己。)
https://www.reddit.com/r/rstats/comments/a34n6b/dplyr_use_previous_row_from_a_column_thats_being/
例如:
library(tidyverse)
df <- tibble("x" = c(NA, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1))
# error: lag cannot refer to a column that still doesn't exist
df %>%
mutate(counter = case_when(is.na(x) ~ coalesce(lag(counter), 0),
x == 0 ~ 0,
x == 1 ~ lag(counter) + 1))
#> Error: Problem with `mutate()` input `counter`.
#> x object 'counter' not found
#> i Input `counter` is `case_when(...)`.
因此,如果您有一个“重置”计数器的条件,则需要编写一个公式来在需要重置时更改组,然后引用 row_number,它将重新启动在组内 1(如@Ronald Shah 和其他人建议):
df %>%
group_by(x1 = cumsum(!coalesce(x, 0))) %>%
mutate(counter = row_number() - 1) %>%
ungroup()
#> # A tibble: 12 x 3
#> x x1 counter
#> <dbl> <int> <dbl>
#> 1 NA 1 NA
#> 2 1 1 1
#> 3 0 2 0
#> 4 0 3 0
#> 5 0 4 0
#> 6 0 5 0
#> 7 1 5 1
#> 8 1 5 2
#> 9 1 5 3
#> 10 1 5 4
#> 11 0 6 0
#> 12 1 6 1
这将是可以证明在 R 中使用 for 循环的少数情况之一:因为备选方案在概念上更难理解。