【问题标题】:Add many calculated columns by grouping variables and then collapse df通过分组变量添加许多计算列,然后折叠 df
【发布时间】:2015-10-14 19:29:26
【问题描述】:

我们有学生级别的数据,其中包含与学区学校教师相关的学生特定年级和科目。

student grade  subject  teacher  school  district female  poverty
1        4       Math     1        1        1       Yes      No
2        4       Math     1        1        1       Yes      No
3        4       Math     1        1        1        No      No
4        4       Math     2        1        1       Yes     Yes
5        4       Math     2        1        1       Yes     Yes
6        4       Math     3        1        1       Yes      No
7        4       Math     4        1        1        No     Yes
8        4       Math     5        1        1        No     Yes
9        4       Math     5        1        1        No     Yes

数据包括任何给定年份和学科的超过 700,000 行,涵盖多个年级和多个地区和学校的教师。

对于每个年级 + 学科 + 学校 + 学区的每一位独特的老师,我们需要

  • (a) 添加列,表明他/她的班级中有多少学生是女性、穷人等,并且
  • (b) 将生成的数据框折叠成一个,每个唯一教师只有一行 每个年级 + 学科 + 学校 + 学区

生成的 df 看起来像 ...

teacher  grade  subject  district  school  pct_fem  pct_poor  ...
1         4       Math     1           1     66.66     0      ...
2         4       Math     1           1    100.00     66.66  ...

等等。

我们一直通过 plyr 来做这件事,就像在

ddply(df, .(teacher, grade, subject, district, school), transform, 
  n_students=length(unique(student)),
  n_fem=length(unique(student[female=="Yes"])), 
  pct_fem = (n_fem/n_students)*100)

但是,这似乎需要很长时间,并且经常会生成一条错误消息,大意是代码找不到 n_fem 或 n_students。

如果我们编写多个 ddply() 语句,一次只生成一列,那么它可以工作,但这显然效率低下,因为我们必须将这些新列合并到一个新的数据帧中,然后将该数据帧折叠到一个记录中每个年级、学科、地区和学校的每位教师。

使用这些大型数据集完成我们想要的目标的最有效方法是什么?任何提示将不胜感激。

【问题讨论】:

  • 请显示您想要的输出。
  • 编辑您的问题而不是发布到 cmets

标签: r dplyr plyr


【解决方案1】:

您可以定义一个函数应用于每个组中的每个列:

prop_Yes = function(x){
  tab = prop.table(table(factor(x,levels=c("Yes","No"))))
  tab[names(tab)=="Yes"]
}

g_vars = c("grade", "subject", "teacher", "school", "district")
p_vars = c("female", "poverty")

这里有几种不同的方法:

基础R

aggregate(DF[p_vars], DF[g_vars], prop_Yes)

  grade subject teacher school district    female poverty
1     4    Math       1      1        1 0.6666667       0
2     4    Math       2      1        1 1.0000000       1
3     4    Math       3      1        1 1.0000000       0
4     4    Math       4      1        1 0.0000000       1
5     4    Math       5      1        1 0.0000000       1

data.table

library(data.table)    
setDT(DF)[ , lapply(.SD, prop_Yes), by=g_vars, .SDcols=p_vars]

   grade subject teacher school district    female poverty
1:     4    Math       1      1        1 0.6666667       0
2:     4    Math       2      1        1 1.0000000       1
3:     4    Math       3      1        1 1.0000000       0
4:     4    Math       4      1        1 0.0000000       1
5:     4    Math       5      1        1 0.0000000       1

dplyr

library(dplyr)
DF %>% group_by_(.dots=g_vars) %>% summarize_each_(funs(prop_Yes), p_vars)

  grade subject teacher school district    female poverty
  (int)   (chr)   (int)  (int)    (int)     (dbl)   (dbl)
1     4    Math       1      1        1 0.6666667       0
2     4    Math       2      1        1 1.0000000       1
3     4    Math       3      1        1 1.0000000       0
4     4    Math       4      1        1 0.0000000       1
5     4    Math       5      1        1 0.0000000       1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 2022-01-04
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多