使用$和列名称向量动态选择数据框列
我希望根据不同的列排序数据框,一个轮到一个。 我有一个字符向量与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]), ]
X
是1: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?