2014-01-16 85 views
2

我有一个包括一大堆关于学生,包括他们现在的学校,故居的邮政编码数据的数据集,和比分:执行多个汇总函数,并返回一个数据帧

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吗?我是新手。

+1

从这里看起来不错。 –

+0

你在代码中有错误。空(.data)中的错误:未找到对象'schools' –

+0

您确定要将分割变量(“ddply”的第二个参数)设置为“zip”吗? 'length(unique(zip))'不会总是返回'1'吗? – rrs

回答

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

使用't'作为对象名称是不明智的,因为在读取代码时它可能与函数't'很容易混淆。 – Roland

+0

好点。纠正! – Troy

相关问题