将列名添加到R中的Foreach输出

时间:2016-11-27 02:08:46

标签: r loops foreach

修改

我花了很长时间才回到这一点,但我终于找到了一个足以解释我问题的简短例子。

foreach(i=1:4,.combine='rbind') %do% {
mymod <- lm(iris[,i] ~ Species, data=iris)
varname <- names(iris)[i]
versicolor.coef <- summary(mymod)$coef[2,1]
versicolor.pval <- summary(mymod)$coef[2,4]
virginica.coef <- summary(mymod)$coef[3,1]
virginica.pval <- summary(mymod)$coef[3,4]
finaldata <- c(varname, versicolor.coef, versicolor.pval, virginica.coef, virginica.pval)
}

输出

         [,1]           [,2]     [,3]                   [,4]    
result.1 "Sepal.Length" "0.93"   "8.77019424057073e-16" "1.582" 
result.2 "Sepal.Width"  "-0.658" "1.83248917685803e-17" "-0.454"
result.3 "Petal.Length" "2.798"  "5.25458742021435e-69" "4.09"  
result.4 "Petal.Width"  "1.08"   "1.25497770422215e-57" "1.78"  
         [,5]                  
result.1 "2.21482134895686e-32"
result.2 "4.53895687858888e-10"
result.3 "4.1061386190517e-91" 
result.4 "7.95174798237392e-86"

首先,有没有办法在最后没有finaldata参数?或者更好地定义我想要在最终输出文件中打印的内容?如果没有,我只是注意到我可以执行类似"varname"=varname的操作,该列将被称为varname,因此这是一种潜在的解决方法。但理想情况下,除了mymod ...

之外,我还希望使用输出的每个值

初次发布

以下是我正在使用的更为复杂的foreach循环的玩具示例:

set.seed(123)
data <- matrix(rnorm(25), nrow=5,ncol=5)

loopdata <- foreach(i=1:ncol(data),.combine=rbind) %dopar% {
  meanval <- mean(data[,i])
  sdval <- sd(data[,i])
  result.data <- c(meanval,sdval)
}

具有以下输出:

> loopdata
                [,1]      [,2]
result.1  0.84504825 1.4647076
result.2 -0.40036228 0.6653162
result.3  1.16711233 0.7605012
result.4 -0.48205580 0.4448445
result.5 -0.07249848 0.7525871

我希望在foreach循环中使用meanvalsdval标记列名。现在,我按照以下方式这样做:

loopdata <- data.frame(loopdata)
names(loopdata) <- c("meanval","sdval")

> loopdata
             meanval     sdval
result.1  0.19357026 0.8110218
result.2 -0.04431897 1.1634896
result.3  0.30790173 0.6394632
result.4  0.10934219 1.4110413
result.5 -0.73314671 0.3445583

一个问题是我的实际代码有一些用户定义的值,这些值可以更改每次都可以生成的可能的列名,并且列的总数以及列名称会有所不同。现在,我使用c()函数将foreach代码末尾的结果连接起来,并根据用户定义代码中可能不同的设置写出不同的c()函数如果别的。生成完整的loopdata后,我通过重新键入列名的潜在选项来分配列名。

我的方法目前很容易发生意外和麻烦。有没有更有效的方法呢?我也愿意考虑其他选择。

2 个答案:

答案 0 :(得分:0)

好吧,而不是使用循环。我们可以试试,

new_df <- data.frame(meanval = colMeans(data), sdval = apply(data, 2, sd))
new_df
#     meanval     sdval
#1  0.19357026 0.8110218
#2 -0.04431897 1.1634896
#3  0.30790173 0.6394632
#4  0.10934219 1.4110413
#5 -0.73314671 0.3445583

或者使用matrixStats包,我们可以使用colSds函数直接获得标准偏差列

library(matrixStats)
new_df <- data.frame(meanval = colMeans(data), sdval = colSds(data))

答案 1 :(得分:0)

我们可以通过在c()步骤

中命名来实现这一目标
library(foreach)
foreach(i= 1:ncol(data), .combine = rbind) %dopar% {
              m1 <-  mean(data[,i])
              sd1 <- sd(data[,i])
              c(meanval= m1, sdval=sd1)
 }
#             meanval     sdval
#result.1  0.19357026 0.8110218
#result.2 -0.04431897 1.1634896
#result.3  0.30790173 0.6394632
#result.4  0.10934219 1.4110413
#result.5 -0.73314671 0.3445583

或者我们可以使用data.table

library(data.table)
as.data.table(data)[, .(meanval=unlist(lapply(.SD, mean)), sdval = unlist(lapply(.SD, sd)))]
#       meanval     sdval
#1:  0.19357026 0.8110218
#2: -0.04431897 1.1634896
#3:  0.30790173 0.6394632
#4:  0.10934219 1.4110413
#5: -0.73314671 0.3445583

或者由于输出的类型相同,我们可以使用一个lapply,然后transpose

setnames(as.data.table(data)[, transpose(lapply(.SD, 
       function(x) c(mean(x), sd(x))))], c('meanval', 'sdval'))[]
#       meanval     sdval
#1:  0.19357026 0.8110218
#2: -0.04431897 1.1634896
#3:  0.30790173 0.6394632
#4:  0.10934219 1.4110413
#5: -0.73314671 0.3445583