我有一个不同列名称的 vector ,并且我希望能够遍历每个列名称,以便从data.frame中提取该列。例如,考虑数据集mtcars和一些存储在字符 vector cols中的变量名。当我尝试使用mtcars的动态子集从cols中选择一个变量时,这些工作将继续

cols <- c("mpg", "cyl", "am")
col <- cols[1]
col
# [1] "mpg"

mtcars$col
# NULL
mtcars$cols[1]
# NULL

我怎样才能得到这些返回相同的值
mtcars$mpg

此外,我如何循环遍历cols中的所有列以获得某种循环中的值。
for(x in seq_along(cols)) {
   value <- mtcars[ order(mtcars$cols[x]), ]
}

最佳答案

您不能使用$进行这种子设置。在源代码(R/src/main/subset.c)中,它指出:



第二个论点?什么?!您必须意识到$与R中的其他所有内容一样(例如(+^等)是一个接受参数并进行求值的函数。 df$V1可以重写为

`$`(df , V1)

或确实
`$`(df , "V1")

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

...例如永远不会工作,也必须先在第二个参数中进行评估的其他任何东西都不会。您只能传递未经评估的字符串。

而是使用[(如果只想提取单个列作为 vector ,则使用[[)。

例如,
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

关于r - 使用$和字符值动态选择数据框列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18222286/

10-11 22:56
查看更多