【问题标题】:How to get group-level statistics while preserving the original dataframe?如何在保留原始数据帧的同时获取组级统计信息?
【发布时间】:2016-10-06 12:15:30
【问题描述】:

我有以下数据框

one <- c('one',NA,NA,NA,NA,'two',NA,NA)
group1 <- c('A','A','A','A','B','B','B','B')
group2 <- c('C','C','C','D','E','E','F','F')

df = data.frame(one, group1,group2)


> df
   one group1 group2
1  one      A      C
2 <NA>      A      C
3 <NA>      A      C
4 <NA>      A      D
5 <NA>      B      E
6  two      B      E
7 <NA>      B      F
8 <NA>      B      F

我想获取one 的每个group1group2 组合的非缺失观察计数。

在 Pandas 中,我会使用 groupby(['group1','group2']).transform,但在 R 中我该怎么做呢?原始数据框很大。

预期输出是:

> df
   one group1 group2 count
1  one      A      C     1
2 <NA>      A      C     1
3 <NA>      A      C     1
4 <NA>      A      D     0
5 <NA>      B      E     1
6  two      B      E     1
7 <NA>      B      F     0
8 <NA>      B      F     0

非常感谢!

【问题讨论】:

  • 您能否通过发布代码来生成您的玩具数据,使此示例可重现?
  • 感谢 ulfelder,如果对你有帮助的话,我有 Python 中的代码
  • 不,请在此处发布 R 代码。否则任何想帮助你的人都必须先跳过几圈。

标签: r data.table dplyr tidyr


【解决方案1】:
library(dplyr)

df %>% group_by(group1, group2) %>% mutate(count = sum(!is.na(one)))
Source: local data frame [8 x 4]
Groups: group1, group2 [4]

     one group1 group2 count
  <fctr> <fctr> <fctr> <int>
1    one      A      C     1
2     NA      A      C     1
3     NA      A      C     1
4     NA      A      D     0
5     NA      B      E     1
6    two      B      E     1
7     NA      B      F     0
8     NA      B      F     0

【讨论】:

  • +1 为整洁的解决方案。我只是补充一下,也许最后ungroup 是个好主意,这样后续操作就不是按组了
【解决方案2】:

data.table:

setDT(df)
df[,count_B:=sum(!is.na(one)),by=c("group1","group2")]

给予:

   one group1 group2 count_B
1: one      A      C       1
2:  NA      A      C       1
3:  NA      A      C       1
4:  NA      A      D       0
5:  NA      B      E       1
6: two      B      E       1
7:  NA      B      F       0
8:  NA      B      F       0

这个想法是在 B 不是 NA 的情况下对真实值(一旦转换为整数)求和,同时按 group1group2 分组。

【讨论】:

  • 如果您的原始 df 真的很大,请仔细查看 data.table。我不是管道的忠实粉丝,所以根本不是教你dplyr的人。对不起。
  • @Noobie 我的意思是 data.table 更快,由于参考工作。管道在 shell 中非常好,但是对于 R 中的多重操作,这并不适用在我看来,因为它要求解释器在调用之间移动引用。
  • @Noobie 不,管道并不简洁,要添加一个可以解决问题的列,尝试添加彼此相关的 5 个,您会发现我根本不喜欢它的原因.
  • 很好的答案。我个人喜欢使用by时的列表语法,它节省了几个引号:by=.(group1,group2)
  • @noobie 如果你知道 pandas,你对 python 有一些背景,试着考虑将一个 dict 传递给一系列函数,每次它得到一个新的内存引用,如果它会在写入时被复制你在通话中修改它。这就是为什么我不喜欢管道:)(不要担心“noobiness”,问没有害处:p)
【解决方案3】:

我们不要忘记base R 可以做很多事情,尽管有时效率不如data.tabledplyr

df$count<-ave(as.integer(df$one),df[,2:3],FUN=function(x) sum(!is.na(x)))
#   one group1 group2 count
#1  one      A      C     1
#2 <NA>      A      C     1
#3 <NA>      A      C     1
#4 <NA>      A      D     0
#5 <NA>      B      E     1
#6  two      B      E     1
#7 <NA>      B      F     0
#8 <NA>      B      F     0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 2019-12-12
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多