具有分类变量catA,catB和catC的示例数据框 . Obs是一些观察到的值 .
catA <- rep(factor(c("a","b","c")), length.out=100)
catB <- rep(factor(1:4), length.out=100)
catC <- rep(factor(c("d","e","f")), length.out=100)
obs <- runif(100,0,100)
dat <- data.frame(catA, catB, catC, obs)
按分类变量的所有可能的数据子集 .
allsubs <- expand.grid(catA = c(NA,levels(catA)), catB = c(NA,levels(catB)),
catC = c(NA,levels(catC)))
> head(allsubs, n=10)
catA catB catC
1 <NA> <NA> <NA>
2 a <NA> <NA>
3 b <NA> <NA>
4 c <NA> <NA>
5 <NA> 1 <NA>
6 a 1 <NA>
7 b 1 <NA>
8 c 1 <NA>
9 <NA> 2 <NA>
10 a 2 <NA>
现在,创建输出数据帧的最简单方法是使用结果列,该结果列包含应用于dat的相应子集(由cat变量组合在每一行中定义)的函数的结果 . 因此输出应该看起来像下面的数据框'whatiwant',其中results列将包含应用于每个子集的函数的结果 .
> whatiwant
catA catB catC results
1 <NA> <NA> <NA> *
2 a <NA> <NA> *
3 b <NA> <NA> *
4 c <NA> <NA> *
5 <NA> 1 <NA> *
6 a 1 <NA> *
7 b 1 <NA> *
8 c 1 <NA> *
9 <NA> 2 <NA> *
10 a 2 <NA> *
因此,如果应用的函数是'mean',结果应该是:
dat$results[1] = mean(subset(dat,)$obs)
dat$results[2] = mean(subset(dat, catA=="a")$obs)
等等..
4 回答
这不是最干净的解决方案,但我认为它接近你想要的 .
由于它是当前编写的,您必须事先构造查找表,但您可以轻松地将该构造移动到函数本身 . 我在最后添加了几行以确保它可以容纳不同长度的输出,因此NaN变成了NA,只是因为它似乎创造了更清洁的输出 . 正如当前编写的那样,在所有列都是NA的情况下,它将函数应用于整个原始数据帧 .
另一种方法,一种是获取所有变量组合的函数,另一种是在所有子集上应用函数 . 组合功能从另一个帖子被盗......
对于allsubs,vars的形式
c("catA","catB","catC"), out.name = "mean".
func需要以ddply将采用的形式编写,这个答案和shwaund之间的一个区别是,这不会返回空子集的行,因此结果列中没有NA .
仅使用矢量化函数和基数R.