假设我有一个简单的销售数据表
> df<-data.frame(country=c("A", "A", "B", "B"), outlet=c(1,2,1,2), sales=c(300, 900,10,40))
> df
country outlet sales
1 A 1 300
2 A 2 900
3 B 1 10
4 B 2 40
并希望添加一个列,显示每个商店贡献的该国家/地区所有销售额的比例。我可以使用split
执行此操作,迭代然后使用rbind
重新组合,但这对我来说非常难看
> do.call("rbind",lapply(split(df, df$country), function(x) { x$frac <- NA; tot<-sum(x$sales); for (o in x$outlet) {s<-x[x$outlet== o,]$sales; x[x$outlet == o,]$frac <- s/tot}; return(x)}))
country outlet sales frac
A.1 A 1 300 0.25
A.2 A 2 900 0.75
B.3 B 1 10 0.20
B.4 B 2 40 0.80
是否有一种更简洁的方式来完成这个简单的任务(除了为它编写一个只是将丑陋的东西扫到脚本中的函数)?
(对于奖励积分,是否有办法阻止rbind
将A.1
等行名添加到生成的data.frame
中?)
答案 0 :(得分:2)
另一种选择:
df$frac <- df$sales / ave(df$sale, df$country, FUN = sum)
df
# country outlet sales frac
#1 A 1 300 0.25
#2 A 2 900 0.75
#3 B 1 10 0.20
#4 B 2 40 0.80
答案 1 :(得分:1)
这是一种更简单的方法
x <- tapply(df$sales, df$country, sum) #total sales by country
df$frac <- df$sales/x[match(df$country, names(x), nomatch=-1)]
df
答案 2 :(得分:0)
您可以直接将新列添加到数据框中,如下所示:
value <- # The code to calculate frac
df$frac <- value
我把它分成两行,使其更具可读性。
您可以在deparse.level = 0
调用中设置rbind
,让函数不构建标签。