在R中使用列名列表对数据框进行子集筛选

10
我想选择保存在字符串变量中的数据框中的所有列。例如:
v1 <- rnorm(100)
v2 <- rnorm(100)
v3 <- rnorm(100)
df <- data.frame(v1,v2,v3)

我希望能够实现以下目标:
df[,c('v1','v2')]

但我希望使用一个变量来代替(c('v1', 'v2'))(这些都失败了):

select.me <- "'v1','v2'"
df[,select.me]
df[,c(select.me)]
df[,c(paste(select.me,sep=''))]

感谢您对一个简单问题的帮助,
注:该段内容已经是中文,无需翻译。
2个回答

22
这里的伟大讽刺是,当你说“我想做这个”时,第一次表达应该成功。
df[,c('v1','v2')]
> str( df[,c('v1','v2')] )
'data.frame':   100 obs. of  2 variables:
 $ v1: num  -0.3347 0.2113 0.9775 -0.0151 -1.8544 ...
 $ v2: num  -1.396 -0.95 -1.254 0.822 0.141 ...

后来所有的尝试都失败了。我后来意识到你不知道可以使用 select.me <- c('v1','v2') ; df[ , select.me]。在某些情况下,您还可以使用以下形式,这可能更加安全:

df[ , names(df) %in% select.me] # logical indexing
df[ , grep(select.me, names(df) ) ]  # numeric indexing
df[ , grepl(select.me, names(df) ) ]  # logical indexing

所有这些内容都可以与否定(!logical)或减号(-numeric)一起使用,以检索补集,而您无法使用字符索引进行否定。如果您想降低理解难度并愿意将select.me的值更改为有效的R表达式,则可以执行以下操作:

select.me <- "c('v1','v2')"
df[ , eval(parse(text=select.me)) ]

并不是我推荐这样做...只是想让你知道在“学会走路”之后这是可能的。使用你最初引用的字符串提取信息也是可以的(虽然有些词藻华丽),但我认为这只是说明你的第一个版本更好)。

select.me <- "'v1','v2'"
df [ , scan(textConnection(select.me), what="", sep=",") ]
> str( df [ , scan(textConnection(select.me), what="", sep=",") ] )
Read 2 items
'data.frame':   100 obs. of  2 variables:
 $ v1: num  -0.3347 0.2113 0.9775 -0.0151 -1.8544 ...
 $ v2: num  -1.396 -0.95 -1.254 0.822 0.141 ...

1
+1 你比我更快地想到了使用eval(parse(...))。顺便提一下,scan函数有一个text参数。 - Matthew Plourde
嗯。你说得对:scan(text=select.me, what="", sep=",") ...这个'text'参数是read.table现在如何处理它的文本参数吗?一定是这样。那么为什么readLines不接受'text'参数呢? - IRTFM
他们添加了一个“text”形式,并检查“file”是否丢失。似乎也可以使用readLines完成。 - IRTFM

13

这是基本的R语法,也许你需要阅读入门手册

select.me <- c('v1','v2')
df[,select.me]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接