【问题标题】:Summarize with conditions based on ranges in dplyr根据 dplyr 中的范围用条件进行总结
【发布时间】:2020-02-07 17:47:53
【问题描述】:

我的例子有一个插图。 样本数据:

 df <- data.frame(ID = c(1, 1, 2, 2, 3, 5), A = c("foo", "bar", "foo", "foo", "bar", "bar"),
 B =     c(1, 5, 7, 23, 54, 202))

df
  ID   A   B
1  1 foo   1
2  1 bar   5
3  2 foo   7
4  2 foo  23
5  3 bar  54
6  5 bar 202

我想做的是按 ID 和相同 ID 的计数进行汇总。此外,我希望基于不同数值范围内 B 值的子组中 ID 的频率(B>=0 和 B=5 和 B=10 和 B=15 & B

我想要这个结果:

  ID count count_0_5 count_5_10 etc
1  1    2          1          1 etc
2  2    2         NA          1 etc
3  3    1         NA         NA etc
4  5    1         NA         NA etc

我使用包dplyr尝试了这段代码:

df %>%
  group_by(ID) %>%
  summarize(count=n(), count_0_5 = n(B>=0 & B<5))

但是,它返回此错误:

`Error in n(B>=0 & B<5) : 
  unused argument (B>=0 & B<5)`

【问题讨论】:

    标签: r dplyr summarize


    【解决方案1】:
    library(dplyr)
    library(tidyr)
    df %>% group_by(ID) %>%
       mutate(B_cut = cut(B, c(0,5,10,15,20,1000), labels = c('count_0_5','count_5_10','count_10_15','count_15_20','count_20_1000')), count=n()) %>% 
       group_by(ID,B_cut) %>% mutate(n=n()) %>% slice(1) %>% select(-A,-B) %>% 
       spread(B_cut, n)
    
    #2nd option
    left_join(df %>% group_by(ID) %>% summarise(n=n()), 
              df %>% mutate(B_cut = cut(B, c(0,5,10,15,20,1000), labels = c('count_0_5','count_5_10','count_10_15','count_15_20','count_20_1000'))) %>% 
                     count(ID,B_cut) %>% spread(B_cut,n), 
              by='ID')
    
    # A tibble: 4 x 5
    # Groups:   ID [4]
         ID count count_0_5 count_5_10 count_20_1000
      <dbl> <int>     <int>      <int>         <int>
    1     1     2         2         NA            NA
    2     2     2        NA          1             1
    3     3     1        NA         NA             1
    4     5     1        NA         NA             1
    

    【讨论】:

    • @Vojtěch Kania 抱歉,我在上一个答案中有一个错误,请检查这个。
    【解决方案2】:

    也许将n(B&gt;=0 &amp; B&lt;5) 替换为sum(B&gt;=0 &amp; B&lt;5)

    这将把满足两个指定条件的案例数相加。

    但是,您将获得 0's 而不是 NA's。这可以通过以下方式解决: ifelse(sum(B&gt;=0 &amp; B&lt;5)&gt;0, sum(B&gt;=0 &amp; B&lt;5), NA)

    我很确定可能会有更好的解决方案(更清晰、更高效),但这应该可行!

    【讨论】:

      猜你喜欢
      • 2020-03-30
      • 2020-10-17
      • 2016-12-30
      • 2018-07-19
      • 2019-03-26
      • 2020-06-25
      • 2017-09-14
      • 2021-06-30
      • 1970-01-01
      相关资源
      最近更新 更多