使用$和列名称向量动态选择数据框列

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

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

我希望遍历parameter的名称并动态选择要用于order数据的列:

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

X1:10 (因为我有10个parameter )。


为了让我的例子可重复的,考虑数据集mtcars并存储在一个字符向量的一些变量名cols 。 当我尝试使用cols的动态子集从mtcars选择一个变量时,采用与上述类似的方式( Q1_R1000$parameter[X] ),未选择该列:

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

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

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

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

`$`(df , V1)

或确实如此

`$`(df , "V1")

但...

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

...例如将永远不会工作,也不会在第二个参数中首先进行评估。 您只能传递一个永远不会被评估的字符串。

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

例如,

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

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

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为排序数据帧提供了一种简单的语法

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

使用NSE版本允许动态构建排序列表可能很有用

sort_list <- c("gear", "desc(mpg)")
mtcars %>% arrange_(.dots = sort_list)
链接地址: http://www.djcxy.com/p/24785.html

上一篇: Dynamically select data frame columns using $ and a vector of column names

下一篇: How to create an example (anonymous) R script to provide a reproducible example?