使用$和列名称向量dynamicselect数据框列

我希望根据不同的栏目,一个轮到一个数据框。 我有一个字符向量与order应该基于的相关列名称:

 parameter <- c("market_value_LOCAL", "ep", "book_price", "sales_price", "dividend_yield", "beta", "TOTAL_RATING_SCORE", "ENVIRONMENT", "SOCIAL", "GOVERNANCE") 

我希望循环“参数”中的名称并dynamicselect要用于order数据的列:

 Q1_R1000_parameter <- Q1_R1000[order(Q1_R1000$parameter[X]), ] 

其中X1:10 (因为我在“参数”中有10个项目)。


为了使我的例子具有可重现性,请考虑数据集“mtcars”和一些存储在字符向量“cols”中的variables名称。 当我尝试使用“cols”的一个dynamic子集从“mtcars”中select一个variables( Q1_R1000$parameter[X] )时,该列未被选中:

 cols <- c("cyl", "am") mtcars$cols[1] # NULL 

你不能用$来做这种子集。 在源代码( R/src/main/subset.c )中说明:

/ * $子操作符。
我们需要确保只评估第一个参数。
第二个将是一个符号,需要匹配,而不是评估。
* /

第二个说法? 什么?! 你必须认识到$和R中的所有其他一样(包括例如(+^ etc)是一个函数,它接受参数并进行求值), df$V1可以被重写为

 `$`(df , V1) 

或确实如此

 `$`(df , "V1") 

但…

 `$`(df , paste0("V1") ) 

…例如将永远不会工作,也不会在第二个参数中首先被评估的任何东西。 你只能传递一个永远不会被评估的string。

相反,使用[ (或[[如果你只想提取一个单一的列作为一个向量)。

例如,

 var <- "mpg" #Doesn't work mtcars$var #These both work, but note that what they return is different # the first is a vector, the second is a data.frame mtcars[[var]] mtcars[var] 

您可以执行没有循环的顺序,使用do.call构造调用order 。 下面是一个可重现的例子:

 # set seed for reproducibility set.seed(123) df <- data.frame( col1 = sample(5,10,repl=T) , col2 = sample(5,10,repl=T) , col3 = sample(5,10,repl=T) ) # We want to sort by 'col3' then by 'col1' sort_list <- c("col3","col1") # Use 'do.call' to call order. Seccond argument in do.call is a list of arguments # to pass to the first argument, in this case 'order'. # Since a data.frame is really a list, we just subset the data.frame # according to the columns we want to sort in, in that order df[ do.call( order , df[ , match( sort_list , names(df) ) ] ) , ] col1 col2 col3 10 3 5 1 9 3 2 2 7 3 2 3 8 5 1 3 6 1 5 4 3 3 4 4 2 4 3 4 5 5 1 4 1 2 5 5 4 5 3 5 

如果我理解正确,你有一个包含variables名称的向量,并希望遍历每个名​​称,并按照他们sorting你的数据框架。 如果是这样,这个例子应该为你说明一个解决scheme。 在你的主要问题(完整的例子是不完整的,所以我不知道你可能会丢失什么)是它应该是order(Q1_R1000[,parameter[X]])而不是order(Q1_R1000$parameter[X]) ,因为参数是一个外部对象,它包含一个与数据框的直接列相对的variables名(当$是合适的时候)。

 set.seed(1) dat <- data.frame(var1=round(rnorm(10)), var2=round(rnorm(10)), var3=round(rnorm(10))) param <- paste0("var",1:3) dat # var1 var2 var3 #1 -1 2 1 #2 0 0 1 #3 -1 -1 0 #4 2 -2 -2 #5 0 1 1 #6 -1 0 0 #7 0 0 0 #8 1 1 -1 #9 1 1 0 #10 0 1 0 for(p in rev(param)){ dat <- dat[order(dat[,p]),] } dat # var1 var2 var3 #3 -1 -1 0 #6 -1 0 0 #1 -1 2 1 #7 0 0 0 #2 0 0 1 #10 0 1 0 #5 0 1 1 #8 1 1 -1 #9 1 1 0 #4 2 -2 -2 

使用dplyr为sorting数据框提供了一个简单的语法

 library(dplyr) mtcars %>% arrange(gear, desc(mpg)) 

使用NSE版本来允许dynamic构buildsorting列表可能是有用的

 sort_list <- c("gear", "desc(mpg)") mtcars %>% arrange_(.dots = sort_list) 
 Q1_R1000[do.call(order, Q1_R1000[parameter]), ]