【问题标题】:Perform multiple summary functions and return a dataframe执行多个汇总函数并返回一个数据框
【发布时间】:2014-01-27 03:52:50
【问题描述】:

我有一个数据集,其中包含有关学生的大量数据,包括他们当前的学校、故居的邮政编码和分数:

students <- read.table(text = "zip  school  score
              43050 'Hunter'    202.72974236
              48227 'NYU'   338.49571519
              48227 'NYU'   223.48658339
              32566 'CCNY'  310.40666224
              78596 'Columbia'  821.59318662
              78045 'Columbia'  853.09842034
              60651 'Lang'  277.48624384
              32566 'Lang'  315.49753763
              32566 'Lang'  80.296556533
              94941 'LIU'   373.53839238
              ",header = TRUE,sep = "")

我想要一堆关于它的汇总数据,每所学校。数据集中每所学校有多少学生,每所学校有多少独特的邮政编码,平均和累积分数。我知道我可以通过使用tapply 创建一堆tmp 帧来获得这个:

tmp.mean <- data.frame(tapply(students$score, students$school, mean))
tmp.sum <- data.frame(tapply(students$score, students$school, sum))
tmp.unique.zip <- data.frame(tapply(students$zip, students$school, function(x) length(unique(x))))
tmp.count <- data.frame(tapply(students$zip, students$school, function(x) length(x)))

给他们更好的列名:

colnames(tmp.unique.zip) <- c("Unique zips")
colnames(tmp.count) <- c("Count")
colnames(tmp.mean) <- c("Mean Score")
colnames(tmp.sum) <- c("Total Score")

然后使用cbind 将它们重新组合在一起:

school.stats <- cbind(tmp.mean, tmp.sum, tmp.unique.zip, tmp.count)

我认为更简洁的方法是:

library(plyr)
school.stats <- ddply(students, .(school), summarise, 
                     record.count=length(score),  
                     unique.r.zips=length(unique(zip)),
                     mean.dist=mean(score), 
                     total.dist=sum(score)
)

生成的数据看起来大致相同(实际上,ddply 方法更简洁,并将学校作为列而不是行名包含在内)。两个问题:有没有更好的方法来找出每所学校有多少条记录?而且,我在这里有效地使用ddply 吗?我是新手。

【问题讨论】:

  • 从这里看起来很不错。
  • 您的代码中有错误。空(.data)错误:找不到对象“学校”
  • 您确定要拆分变量(ddply 的第二个参数)为“zip”吗? length(unique(zip)) 不会总是返回 1
  • @WilmerEHenaoH 实际上有两个错误。固定的。真实数据有点不同,所以我做了一些翻译。
  • 我同意@CarlWitthoft,这看起来不错。

标签: r plyr


【解决方案1】:

如果性能有问题,您也可以使用data.table

require(data.table)
tab_s<-data.table(students)
setkey(tab_s,school)
tab_s[,list(total=sum(score),
        avg=mean(score),
        unique.zips=length(unique(zip)),
        records=length(score)),
   by="school"]

     school     total      avg unique.zips records
1:   Hunter  202.7297 202.7297           1       1
2:      NYU  561.9823 280.9911           1       2
3:     CCNY  310.4067 310.4067           1       1
4: Columbia 1674.6916 837.3458           2       2
5:     Lang  673.2803 224.4268           2       3
6:      LIU  373.5384 373.5384           1       1

【讨论】:

  • 使用t作为对象名是不明智的,因为它在阅读代码时很容易与函数t混淆。
【解决方案2】:

评论似乎大体一致:这看起来不错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 2012-02-11
    • 2016-06-08
    • 2014-08-04
    • 2021-05-12
    相关资源
    最近更新 更多