如何根据包含其名称的另一列获取列的值?
例:
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
答案 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
>
答案 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