向数据框中添加派生数据列

3
假设我有一个简单的销售数据表。
> 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向生成的data.frame添加类似于A.1的行名称?)

3个回答

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
这是一个更简单的方法。
x <- tapply(df$sales, df$country, sum) #total sales by country
df$frac <- df$sales/x[match(df$country, names(x), nomatch=-1)] 
df

0

你可以直接将新列添加到数据帧中,如下所示:

value <- # The code to calculate frac
df$frac <- value

我将它分成两行以使其更易读。
您可以在rbind调用中设置deparse.level = 0,以使该函数不构建标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接