汇总或汇总以获得比率

时间:2010-12-02 23:39:06

标签: r aggregate

以下是一个玩具问题,可以解释我的问题。

我有一个包含大量员工的数据框;对于每个员工,它有一个名称,工资,性别和州。

aggregate(salary ~ state)  # Returns the average salary per state
aggregate(salary ~ state + gender, data, FUN = mean)  # Avg salary per state/gender

我实际需要的是每个州妇女总薪水的比例摘要。

aggregate(salary ~ state + gender, data, FUN = sum)  

返回每个州的女性(和男性)所获得的总薪水,但我真正需要的是每州一级的salary_w / salary_total。我可以写一个for循环等等 - 但我想知道是否有某种方法可以使用聚合来做到这一点。

6 个答案:

答案 0 :(得分:8)

另一个选择是使用plyr。 ddply()期望将data.frame作为输入,并将data.frame作为输出返回。第二个参数是您希望如何拆分数据框。第三个参数是我们想要应用于块的内容,这里我们使用summarise从现有的data.frame创建一个新的data.frame。

library(plyr)

#Using the sample data from kohske's answer above

> ddply(d, .(state), summarise, ratio = sum(salary[gender == "Woman"]) / sum(salary))
  state     ratio
1     1 0.5789860
2     2 0.4530224

答案 1 :(得分:3)

可能会重塑或重塑2会对你的工作有所帮助。

以下是一个示例脚本:

library(reshape2) # from CRAN

# sample data
d <- data.frame(expand.grid(state=gl(2,2),gender=gl(2,1, labels=c("Men","Wemon"))),
  salaly=runif(8))

d2 <- dcast(d, state~gender, sum)
d2$frac <- d2$Wemon/(d2$Men+d2$Wemon)

答案 2 :(得分:2)

ave函数适用于此类问题。

Data$ratio <- ave(Data$salary, Data$state, Data$gender, FUN=sum) /
              ave(Data$salary, Data$state, FUN=sum)

答案 3 :(得分:2)

另一种解决方案是使用xtabsprop.table

prop.table(xtabs(salary ~ state + gender,data),margin=1)

答案 4 :(得分:1)

通常不建议将数据集命名为“数据”,因此我将稍微更改问题以命名数据集“dat1”。

       with( subset(dat1, gender="Female"), aggregate(salary, state, sum )/ 
 # should return a vector
       with( data=dat1,                   aggregate(salary,  state, sum ) 
             # using R's element-wise division

我认为你也在使用附加,并且有充分的理由重新考虑这个决定,尽管你可能会在克劳利读到这些内容。

答案 5 :(得分:1)

由于您希望以每个州为基础的结果,tapply可能就是您想要的。

为了说明让我们生成一些任意数据:

set.seed(349)   # For replication
n <- 20000      # Sample size
gender <- sample(c('M', 'W'), size = n, replace = TRUE) # Random selection of gender
state <- c('AL','AK','AZ','AR','CA','CO','CT','DE','DC','FL','GA','HI',
           'ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN',
           'MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH',
           'OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA',
           'WV','WI','WY')      # All US states
state <- sample(state, size = n, replace = TRUE)  # Random selection of the states

state_index <- tapply(state, state)     # Just for the data generatino part ...
gender_index <- tapply(gender, gender)

# Generate salaries
salary <- runif(length(unique(state)))[state_index]     # Make states different
salary <- salary + c(.02, -.02)[gender_index]           # Make gender different
salary <- salary + log(50) + rnorm(n)                   # Add mean and error term
salary <- exp(salary)                                   # The variable of interest

你要求的是,每个州妇女的工资总额和每个州的总工资总和:

salary_w <- tapply(salary[gender == 'W'], state[gender == 'W'], sum)
salary_total <- tapply(salary, state, sum)

或者如果它在数据框中:

salary_w <- with(myData, tapply(salary[gender == 'W'], state[gender == 'W'], sum))
salary_total <- with(myData, tapply(salary, state, sum))

然后答案是:

> salary_w / salary_total
       AK        AL        AR        AZ        CA        CO        CT        DC 
0.4667424 0.4877013 0.4554831 0.4959573 0.5382478 0.5544388 0.5398104 0.4750799 
       DE        FL        GA        HI        IA        ID        IL        IN 
0.4684846 0.5365707 0.5457726 0.4788805 0.5409347 0.4596598 0.4765021 0.4873932 
       KS        KY        LA        MA        MD        ME        MI        MN 
0.5228247 0.4955802 0.5604342 0.5249406 0.4890297 0.4939574 0.4882687 0.5611435 
       MO        MS        MT        NC        ND        NE        NH        NJ 
0.5090843 0.5342312 0.5492702 0.4928284 0.5180169 0.5696885 0.4519603 0.4673822 
       NM        NV        NY        OH        OK        OR        PA        RI 
0.4391634 0.4380065 0.5366625 0.5362918 0.5613301 0.4583937 0.5022793 0.4523672 
       SC        SD        TN        TX        UT        VA        VT        WA 
0.4862358 0.4895377 0.5048047 0.4443220 0.4881062 0.4880047 0.5338397 0.5136393 
       WI        WV        WY 
0.4787588 0.5495602 0.5029816