【问题标题】:Count Complete Cases per Group计算每组的完整案例
【发布时间】:2015-01-14 13:11:17
【问题描述】:

我有一个大数据集(大约 10 000 行),并且想要创建一个函数来计算每组的完整案例(而不是 NA)的数量。我尝试了各种函数(聚合、表格、求和(完成.cases)、group_by 等),但不知何故我错过了一个 - 可能是小技巧。感谢您的帮助!

一个小样本数据集解释一下,我需要的结果。

x <- data.frame(group = c(1:4), 
                age = c(4:1, c(11, NA,13, NA)), 
                speed = c(12, NA,15,NA))
print(x)
#  group age speed
#1     1   4    12
#2     2   3    NA
#3     3   2    15
#4     4   1    NA
#5     1  11    12
#6     2  NA    NA
#7     3  13    15
#8     4  NA    NA

我写的一个函数如下:

CountPerGroup <- function(group) {
    data.set <- subset(x,group %in% group)

    vect <- vector()
    for (i in 1:length(group)) {
        vect[i] <- sum(complete.cases(data.set))
    }
    output <- data.frame(cbind(group,count=vect))   
    return(output)

}

结果

CountPerGroup(2:1)

  group count
1     2     4
2     1     4

很遗憾,这是错误的。相反,结果应该是这样的

  group count
1     2     1
2     1     4

我错过了什么?我如何告诉 R 每组 来计算 complete.cases? 非常感谢您对此提供的任何帮助!

【问题讨论】:

  • 对不起,我没有得到正确的结果......也许我没有正确使用你的行 - 你将如何在函数中实现它?
  • 第1组4个完整病例和第2组1个完整病例怎么算?请注意,完整的案例与非缺失值的数量相同
  • 如果数据量大,也可以使用data.table,这个包经常是为了这个效果做的!

标签: r function count


【解决方案1】:

如果你想保持你的功能,类似的东西应该可以解决问题:

x <- data.frame(group = c(1:4), 
                age = c(4:1, c(11, NA,13, NA)), 
                speed = c(12, NA,15,NA))

CountPerGroup <- function(x, groups) {
  data.set <- subset(x, group %in% groups)
  ans <- sapply(split(data.set, data.set$group), 
                function(y) sum(complete.cases(y)))
  return(data.frame(group = names(ans), count = unname(ans)))
}


CountPerGroup(x, 1:2)
#  group count
#1     1     2
#2     2     0

据我所知,这是正确的。但它与您建议的结果不符。

编辑

您似乎希望将非NA 的数量改为正确排序。改用这个函数:

CountPerGroup2 <- function(x, groups) {
   data.set <- subset(x, group %in% groups)
   ans <- sapply(split(data.set, data.set$group), 
                 function(y) sum(!is.na(y[, !grepl("group", names(y))])))[groups]
   return(data.frame(group = names(ans), count = unname(ans)))
}

CountPerGroup2(x, 2:1)
#  group count
#1     2     1
#2     1     4

【讨论】:

  • 数据集有两行用于第 1 组,2 行用于第 2 组。第 1 组有四个值 4(年龄)、11(年龄)、12(速度)、12(速度)。第 2 组的年龄值为 2,但第 6 行中的年龄为 NA,速度有两个 NA。所以我计算了组 1 的 4 个值(= 观察值)和组 2 的值。
  • @user2006697 啊哈。所以你想要观察的数量(即非缺失值)。我明白了,我会修改答案。请注意,这与完整案例的数量相同。完整案例是没有 NA 的整行。
  • Ahhhh....感谢您的解释...我显然误解了 complete.cases 功能。感谢这一点 - 以及您修改后的答案!
  • 太棒了!感谢您的帮助和耐心!
  • 还有一个问题:这段代码忽略了函数中组的顺序。 IE。不管我使用的是 CountPerGroup2(x, 1:2) 还是 CountPerGroup2(x, 2:1)。如何更改您的代码,以便将函数输入中的顺序考虑在内?
【解决方案2】:

如果您只是在寻找一种方法来获取每组非 NA 值的完整计数,您可以使用类似的方法:

library(plyr)
x <- data.frame(group = c(1:4), 
                age = c(4:1, c(11, NA,13, NA)), 
                speed = c(12, NA,15,NA))

counts <- ddply(x, "group", summarize, count=sum(!is.na(c(age, speed))))

##   group count
## 1     1     4
## 2     2     1
## 3     3     4
## 4     4     1

您确实错过了一个函数,它可以让您查询组的子集,但您可以通过单线方法来计算完整的解决方案。

【讨论】:

    【解决方案3】:

    这是data.table的一种方式

    library(data.table)
    library(functional)
    
    countPerGroup = function(x, vec)
    {
        dt = data.table(x) 
        d1 = setkey(dt, group)[group %in% vec]
        d2 = d1[,lapply(.SD, Compose(Negate(is.na), sum)),by=group]
        transform(d2, count=age+speed, speed=NULL, age=NULL)
    }
    
    
    countPerGroup(x, 1:2)
    #   group count
    #1:     1     4
    #2:     2     1
    
    countPerGroup(x, c(1,2))
    #   group count
    #1:     1     4
    #2:     2     1
    

    如果您的data.table 中的行数较多,则特别高效!

    【讨论】:

    • 谢谢。目前对我来说有点太高级了,但我保存了它以备将来使用!
    • Compose 和 Negate 是功能包中非常直观的功能,你应该看看!
    【解决方案4】:

    我刚遇到同样的问题,找到了一个更简单的解决方案

    库(data.table)

    x <- data.table(group = c(1:4), 
                    age = c(4:1, c(11, NA,13, NA)), 
                    speed = c(12, NA,15,NA))
    x[,sum(complete.cases(.SD)), by=group]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-01
      • 2021-08-01
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      相关资源
      最近更新 更多