计算某列中某个值的出现次数

时间:2019-03-11 12:38:46

标签: r dplyr

我的数据框中有一列如下所示:

> df
# A tibble: 20 x 1
   duration
      <dbl>
 1     0   
 2    40.0 
 3   247.  
 4    11.8 
 5   116.  
 6    10.2 
 7   171.  
 8     7.58
 9    87.8 
10    23.2 
11   390.  
12    35.8 
13     4.73
14    29.1 
15     0   
16    36.8 
17    73.8 
18    12.9 
19   124.  
20    10.7

我需要对这些数据进行分组,以便所有从0开始到下一个零之前的最后一行的行都在一个组中。我已经使用for循环完成了此操作:

counter <- 0

df$group <- NA
df$group[1] <- 1

for (i in 2:NROW(df)) {
  df$group[i] <-
    ifelse(df$duration[i] == 0, df$group[i - 1] + 1, df$group[i - 1])
}

这给了我想要的输出:

> df
# A tibble: 20 x 2
   duration group
      <dbl> <dbl>
 1     0        1
 2    40.0      1
 3   247.       1
 4    11.8      1
 5   116.       1
 6    10.2      1
 7   171.       1
 8     7.58     1
 9    87.8      1
10    23.2      1
11   390.       1
12    35.8      1
13     4.73     1
14    29.1      1
15     0        2
16    36.8      2
17    73.8      2
18    12.9      2
19   124.       2
20    10.7      2

但是由于我的原始数据帧很大,所以我正在寻找一种更快的解决方案,并且我一直在尝试使其与dplyr一起使用,但无济于事。其他相关问题正在计算当前值出现的频率,而不是特定值,因此我还没有找到解决该问题的方法。

感谢您为我的问题找到矢量化解决方案的帮助,谢谢!以下是示例数据:

df <-
  structure(
    list(
      duration = c(
        0,
        40.0009999275208,
        247.248000144958,
        11.8349997997284,
        115.614000082016,
        10.2449998855591,
        171.426000118256,
        7.58200001716614,
        87.805999994278,
        23.1909999847412,
        390.417999982834,
        35.8229999542236,
        4.73100018501282,
        29.0869998931885,
        0,
        36.789999961853,
        73.8420000076294,
        12.8770000934601,
        123.771999835968,
        10.7190001010895
      )
    ),
    row.names = c(NA,-20L),
    class = c("tbl_df", "tbl", "data.frame")
  )

1 个答案:

答案 0 :(得分:1)

我们可以使用cumsum如下创建所需的列

df %>% 
  mutate(grp = cumsum(duration == 0))
# A tibble: 20 x 2
#   duration   grp
#      <dbl> <int>
# 1     0        1
# 2    40.0      1
# 3   247.       1
# 4    11.8      1
# 5   116.       1
# 6    10.2      1
# 7   171.       1
# 8     7.58     1
# 9    87.8      1
#10    23.2      1
#11   390.       1
#12    35.8      1
#13     4.73     1
#14    29.1      1
#15     0        2
#16    36.8      2
#17    73.8      2
#18    12.9      2
#19   124.       2
#20    10.7      2