我正在使用ddply来聚合和汇总数据框变量,我有兴趣循环遍历我的数据框列表以创建新变量。
new.data <- ddply(old.data,
c("factor", "factor2"),
function(df)
c(a11_a10 = CustomFunction(df$a11_a10),
a12_a11 = CustomFunction(df$a12_a11),
a13_a12 = CustomFunction(df$a13_a12),
...
...
...))
我有没有办法在ddply中插入一个循环,以便我可以避免写出每个新的汇总变量,例如。
for (i in 11:n) {
paste("a", i, "_a", i - 1) = CustomFunction(..... )
}
我知道这不是实际完成的方式,但我只是想表明我是如何构思它的。有没有办法在ddply或通过列表调用的函数中执行此操作?
更新:因为我是新用户,所以我无法回答自己的问题:
我的回答涉及Nick的回答和Ista评论的想法:
func <- function(old.data, min, max, gap) {
varrange <- min:max
usenames <- paste("a", varrange, "_a", varrange - gap, sep="")
new.data <- ddply(old.data,
.(factor, factor2),
colwise(CustomFunction, c(usenames)))
}
答案 0 :(得分:7)
在@Nick的优秀答案的基础上,这是解决问题的一种方法
foo <- function(df){
names = paste("a", 11:n, "_a", 10:(n-1), sep = "")
results = sapply(df[,names], CustomFunction)
}
new.data = ldply(dlply(old.data, c("factor", "factor2")), foo)
以下是使用tips
中ggplot2
数据集的示例应用程序。假设我们想要通过tip
和total_bill
的组合来计算sex
和smoker
的平均值,以下是代码的工作原理
foo = function(df){names = c("tip", "total_bill"); sapply(df[,names], mean)}
new = ldply(dlply(tips, c("sex", "smoker")), foo)
它产生如下所示的输出
.id tip total_bill
1 Female.No 2.773519 18.10519
2 Female.Yes 2.931515 17.97788
3 Male.No 3.113402 19.79124
4 Male.Yes 3.051167 22.28450
这是你在找什么?
答案 1 :(得分:4)
如果我理解正确,您基本上想要将自定义函数应用于ddply
data.frame中的每一列。
好消息是有一个ddply
函数正是这样做的。这意味着您的问题的解决方案归结为一个班轮:
以@Ramnath的优秀例子为基础:
library(ggplot2)
customfunction <- mean
ddply(tips, .(sex, smoker), numcolwise(customfunction))
sex smoker total_bill tip size
1 Female No 18.10519 2.773519 2.592593
2 Female Yes 17.97788 2.931515 2.242424
3 Male No 19.79124 3.113402 2.711340
4 Male Yes 22.28450 3.051167 2.500000
这样做的原因是colwise
将一个对矢量起作用的函数转换为一个函数,该函数适用于data.frame中的一列。 colwise
有两种变体:numcolwise
仅适用于数字列,catcolwise
适用于分类列。有关详细信息,请参阅?colwise
。
编辑:
我感谢您可能不希望将该函数应用于data.frame中的所有列。尽管如此,我发现这种语法非常简单,我的一般方法是修改传递给ddply
的data.frame。例如,以下修改示例子集tips
可以排除某些列。解决方案仍然是单线:
ddply(tips[, -2], .(sex, smoker), numcolwise(customfunction))
sex smoker total_bill size
1 Female No 18.10519 2.592593
2 Female Yes 17.97788 2.242424
3 Male No 19.79124 2.711340
4 Male Yes 22.28450 2.500000
答案 2 :(得分:3)
分步骤:
varrange<-11:n
usenames<-paste("a", varrange, "_a", varrange - 1, sep="")
results<-sapply(usenames, function(curname){CustomFunction(df[,curname])})
names(results)<-usenames
这是你想要的吗?