连续求和 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 = 0counter 保持为 NA,其中 xNA

欢迎@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 循环的少数情况之一:因为备选方案在概念上更难理解。