Sam*_*ong 103 r dataframe r-faq
我希望根据不同的列来订购数据框,一个转弯.我有一个字符向量,其中的相关列名order应该基于:
parameter <- c("market_value_LOCAL", "ep", "book_price", "sales_price", "dividend_yield",
"beta", "TOTAL_RATING_SCORE", "ENVIRONMENT", "SOCIAL", "GOVERNANCE")
Run Code Online (Sandbox Code Playgroud)
我想循环遍历名称parameter并动态选择要用于order我的数据的列:
Q1_R1000_parameter <- Q1_R1000[order(Q1_R1000$parameter[X]), ]
Run Code Online (Sandbox Code Playgroud)
这里X是1:10(因为我有10个项目parameter).
为了使我的示例可重现,请考虑mtcars存储在字符向量中的数据集和一些变量名称cols.当我尝试mtcars使用动态子集选择变量时cols,以与上面(Q1_R1000$parameter[X])相似的方式,未选择该列:
cols <- c("cyl", "am")
mtcars$cols[1]
# NULL
Run Code Online (Sandbox Code Playgroud)
Sim*_*lon 164
你无法做那种子集化$.在源代码(R/src/main/subset.c)中,它声明:
/*$ subset运算符.
我们需要确保只评估第一个参数.
第二个是需要匹配的符号,而不是评估符号.
*/
第二个论点?什么?!你必须认识到$,像R中的一切(包括例如(,+,^等)是一个函数,接受参数,并进行评估.df$V1可以改写为
`$`(df , V1)
Run Code Online (Sandbox Code Playgroud)
或者确实
`$`(df , "V1")
Run Code Online (Sandbox Code Playgroud)
但...
`$`(df , paste0("V1") )
Run Code Online (Sandbox Code Playgroud)
...例如永远不会工作,也不会在第二个参数中首先评估任何其他东西.您只能传递一个永远不会被评估的字符串.
而是使用[(或者[[如果您只想提取单个列作为向量).
例如,
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]
Run Code Online (Sandbox Code Playgroud)
您可以执行无循环的排序,使用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
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,您有一个包含变量名称的向量,并且希望循环遍历每个名称并按它们对数据框进行排序。如果是这样,这个例子应该为您说明一个解决方案。您的主要问题(完整的示例不完整,所以我不确定您可能还缺少什么)是它应该代替order(Q1_R1000[,parameter[X]]),order(Q1_R1000$parameter[X])因为参数是一个外部对象,其中包含与直接列相反的变量名您的数据框(当$合适时)。
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
Run Code Online (Sandbox Code Playgroud)
使用dplyr提供了一种用于对数据帧进行排序的简单语法
library(dplyr)
mtcars %>% arrange(gear, desc(mpg))
Run Code Online (Sandbox Code Playgroud)
使用此处所示的NSE版本以允许动态构建排序列表可能会很有用。
sort_list <- c("gear", "desc(mpg)")
mtcars %>% arrange_(.dots = sort_list)
Run Code Online (Sandbox Code Playgroud)
我会实现packagesym的功能rlang。假设 的col值为"mpg"。这个想法是对其进行子集化。
mtcars %>% pull(!!sym(col))
# [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0
# [32] 21.4
Run Code Online (Sandbox Code Playgroud)
继续编码!
| 归档时间: |
|
| 查看次数: |
95762 次 |
| 最近记录: |