以下是一个玩具问题,可以解释我的问题。
我有一个包含大量员工的数据框;对于每个员工,它有一个名称,工资,性别和州。
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循环等等 - 但我想知道是否有某种方法可以使用聚合来做到这一点。
答案 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)
另一种解决方案是使用xtabs
和prop.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