我在网上广泛查看并没有看到这个特定问题的答案(我认为)。
我解释自己的最好方法是使用一些代码来复制我的问题。 我做了一些临时数据:
x <- runif(100,1,2)
y <- runif(100,2,3)
z <- c(rep(1,100))
temp <- cbind(x,y,z)
temp[1:25,3] = temp[1:25,3] +2
temp <- as.data.frame(temp)
这就是临时的样子
x y z
1 1.512620 2.552271 3
2 1.133614 2.455296 3
3 1.543242 2.490120 3
4 1.047618 2.069474 3
. . . .
. . . .
27 1.859012 2.687665 1
28 1.231450 2.196395 1
并一直持续到数据帧结束(100行)。
我想要做的是将一个函数应用于数据框BUT到数据的子集。因此,例如,我想在z = 3时将函数mean应用于x和y列,并在z = 1时将函数mean应用于x和y列。所以我最终会得到4个值:当z = 1且z = 3时x的平均值和z = 1且z = 3时y的平均值。对于我的实际数据集,z =某个值时的行数变化很大。
我一直在使用以下代码,它可以正常工作;然而,它让我感到非常不安,因为我觉得代码可以更高效,理想情况下避免for循环。
x <- c(unique(temp$z))
我使用^^来获得唯一的z值(在这种情况下,z = 3和z = 1)。
for(i in x){
assign(paste("newdata",i,sep=""),subset(temp[which(temp$z==i),],select=c("x","y")))
}
所以我现在有两个新数据帧newdata1和newdata3没有相同的行数。当z = 1时,newdata1具有所有值,而当z = 3时,newdata3具有所有值。
library(gdata)
blah <-cbindX(newdata1,newdata3)
我使用cbindX将子集化数据再次组合成一个大数据帧。我不确定为什么我这样做(我很久以前就制作了这段代码)。我记得的是,当我使用上面的for循环时,这是我能够使它工作的唯一方法。代码的主要问题是当我有多个z值然后手动输入该列表变得非常麻烦。如果z的范围是1到50,那么用户可以键入newdata1,newdata2,newdata3 ....等等。
但是......确实有效:
summ.test <- apply(blah,2,function(x) {
c(min(x,na.rm=TRUE),median(x,na.rm=TRUE),max(x,na.rm=TRUE),sum(!is.na(x)))})
x y x y
[1,] 1.028332 2.018162 1.012379 2.009595
[2,] 1.509049 2.504000 1.427981 2.455296
[3,] 1.992704 2.998483 1.978359 2.970695
[4,] 75.000000 75.000000 25.000000 25.000000
所以我实际上做的是创建一个新的数据框,其中包含我之前的子集化值,并将感兴趣的函数应用于它们。所以第一行是:z = 1时的平均值,z = 1时的平均值,z = 3时的平均值,z = 3时的平均值。
主要问题应该是相当明显的:用于子集数据框的for循环方法会导致更多问题,我希望如此。有什么建议可以完全避免这种情况并最终得到相同的结果吗?
如果其中任何一个令人困惑,或者我的代码只是简单的马虎,请告诉我!仍在努力格式化本网站上的问题..
答案 0 :(得分:3)
library(data.table)
DT <- as.data.table(temp)
DT[, lapply(.SD, mean), by=z]
z x y
1: 3 1.515801 2.309161
2: 1 1.509637 2.532575
或使用基础R
:
with(temp, cbind(x=tapply(x, z, mean), y=tapply(y, z, mean)))
x y
1 1.509637 2.532575
3 1.515801 2.309161
PS,别忘了设置一个种子,set.seed(1)
作为例子;)
答案 1 :(得分:2)
> aggregate( . ~ z, data=temp, FUN=mean)
z x y
1 1 1.505304 2.474642
2 3 1.533418 2.477191
当您将相同的函数应用于另一列的类别中的多个列时,请考虑“聚合”。这是版本taht采用公式参数,其中波浪号之前的“点”表示获得除“z”之外的所有列的平均值。
答案 2 :(得分:1)
我想要做的是将一个函数应用于数据框BUT到数据的子集。
因此,您可以使用subset
或aggregate
功能:
data = data.frame(x = runif(100), y = runif(100), z = sample(1:10, 100, replace = TRUE))
# get z > 3 AND z < 6 subset, for example
new.data = subset(data, z > 3 & z < 6) ## CAUTION: use &, not &&
# use newdata
cm = colMeans(new.data)
print(cm)
# x y z
# 0.4674450 0.5293915 4.5769231
希望它有所帮助!