我有一个数据集,其中包含大量关于学生的数据,包括他们当前的学校,以前住所的邮政编码和分数:
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 = "")
我想要一堆关于它的摘要数据,每所学校。每个学校有多少学生在数据集中,每个学校有多少独特的zipcodes,平均和累积分数。我知道我可以使用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
吗?我是新手。
答案 0 :(得分:3)
如果性能有问题,您也可以使用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
答案 1 :(得分:0)
评论似乎达成了一致意见:这看起来不错。