当列名在变量中时获取列的值

时间:2018-01-03 18:30:06

标签: r

如何根据包含其名称的另一列获取列的值?

例:

onDestroyView()

输出:

set.seed(1)
df <- data.frame(variable = c("var1", "var2", "var1", "var3")
             , var1 = rnorm(4)
             , var2 = rnorm(4)
             , var3 = rnorm(4))

  variable       var1       var2       var3
1     var1 -0.6264538  0.3295078  0.5757814
2     var2  0.1836433 -0.8204684 -0.3053884
3     var1 -0.8356286  0.4874291  1.5117812
4     var3  1.5952808  0.7383247  0.3898432

3 个答案:

答案 0 :(得分:2)

# Make sure `df$variable` is not a factor
df$variable = as.character(df$variable)

# Subset and convert to matrix in order to take diagonal entries:
diag(as.matrix(df[df$variable]))

答案 1 :(得分:2)

这也可以通过简单的for()循环和提取运算符[来完成。

set.seed(1)
df <- data.frame(variable = c("var1", "var2", "var1", "var3")
                 , var1 = rnorm(4)
                 , var2 = rnorm(4)
                 , var3 = rnorm(4),
                 stringsAsFactors=FALSE)
aResult <- NULL
# use extract operator with indexed reference to variable column
for(i in 1:nrow(df)) aResult[i] <- df[i,df[i,"variable"]]
aResult 

...和输出:

> aResult
[1] -0.6264538 -0.8204684 -0.8356286  0.3898432
> 

同样,我们可以使用sapply()替换for()循环。

aResult&lt; - sapply(1:nrow(df),function(x,y){                      DF [X,DF [X,&#34;可变&#34;]]               },Y = DF)

...和输出:

> aResult2 <- sapply(1:nrow(df),function(x,y){
+                 df[x,df[x,"variable"]]
+      },y=df)
> aResult2
[1] -0.6264538 -0.8204684 -0.8356286  0.3898432
> 

对备选方案进行基准测试

鉴于至少有三种不同的方法来解决这个问题(即使用OP评论中提到的diag()函数和另一个答案),值得一提的是,一种方法是否显着比其他人快。我们可以使用microbenchmark包来回答这个问题。

为了让R在问题上花费更多时间,我们将创建一个包含500列和10,000行的数据框。

rowCount <- 10000
varCount <- 500
variable <- paste0(rep("X",rowCount),rep(1:varCount,rowCount / varCount))

df <- cbind(variable,
            data.frame(matrix(runif(rowCount * 
                       varCount),nrow=rowCount,ncol=varCount)),
            stringsAsFactors=FALSE)

接下来,我们将使用microbenchmark包来比较这三种方法。

library(microbenchmark)

myForLoop <- function(){
     for(i in 1:nrow(df)) aResult[i] <- df[i,df[i,"variable"]]
}

myDiag <- function(){
     diag(as.matrix(df[df$variable]))
}
mySapply <- function() {
     sapply(1:nrow(df),function(x,y){
          df[x,df[x,"variable"]]
         },y=df)
}
funcList <- list(myForLoop=myForLoop,myDiag=myDiag,mySapply=mySapply)

microbenchmark(list=funcList,unit="ns",times=1000L)

当我们在每种方法上运行1000次基准测试时,我们得到以下结果,说明这三种方法具有非常相似的性能特征。平均最快的方法比最慢的平均速度快不到1 ns。鉴于计算机上运行的其他进程可能会导致基准测试的变化,我们得出结论,平均响应时间没有显着差异。

> theModel <- microbenchmark(list=funcList,unit="ns",times=1000L)
> autoplot(theModel)
> print(theModel)
Unit: nanoseconds
      expr min lq  mean median uq max neval cld
 myForLoop   2  7 6.981      7  7 361  1000   a
    myDiag   2  7 7.160      7  8 260  1000   a
  mySapply   2  7 6.613      7  7  93  1000   a
> 

enter image description here

答案 2 :(得分:1)

第一步:将df分成每行的列表

df <- data.frame(variable = c("var1", "var2", "var1", "var3")
             , var1 = rnorm(4)
             , var2 = rnorm(4)
             , var3 = rnorm(4))

xy.list <- split(df, seq(nrow(df))) 

第二步:最小化函数,选择与变量名称匹配的每个元素的每一列

 sel<-function(x){x[x$variable]}

第三步:使用Map()

将此函数应用于每个元素
  result<-map(xy.list,sel )
  unlist( flatten(result)  )

输出:

 > unlist( flatten(result)  )
  var1       var2       var1       var3 
 -0.6264538 -0.8204684 -0.8356286  0.3898432