将data.frame列转换为向量?

222

我有一个类似这样的数据框:

a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)

我尝试了以下的代码将其中一列转化为向量,但是它并没有起作用:

avector <- as.vector(aframe['a2'])
class(avector) 
[1] "data.frame"

这是我能想到的唯一解决方案,但我假设必须有更好的方法来完成此任务:

class(aframe['a2']) 
[1] "data.frame"
avector = c()
for(atmp in aframe['a2']) { avector <- atmp }
class(avector)
[1] "numeric"

注意: 我上面使用的词汇可能不准确,如果是这样,请纠正我。我仍在学习R的世界。此外,任何关于这里正在发生什么的解释都会受到赞赏(例如与Python或其他语言相关的解释会有所帮助!)


5
如您所见,对?'[.data.frame']的仔细阅读将帮助您深入了解该主题。请注意,在不改变原意的情况下,我会尽力使翻译通俗易懂。 - joran
12个回答

265

我将尝试在不犯任何错误的情况下解释这个问题,但我敢打赌,这会在评论中引起一些澄清。

数据框是一个列表。当你用列名和 [ 来子集化一个数据框时,你得到的是一个 子列表(或者说是一个子数据框)。如果你想要实际的原子列,可以使用 [[,或有点令人困惑的是(对我来说),你可以使用 aframe[,2],它返回一个向量,而不是一个子列表。

因此,请尝试运行这个序列,也许事情会更清楚:

avector <- as.vector(aframe['a2'])
class(avector) 

avector <- aframe[['a2']]
class(avector)

avector <- aframe[,2]
class(avector)

7
这很有用。我已经习惯使用aframe[,"a2"],因为它可以用于数据框和矩阵,而且似乎能获得相同的结果——一个向量。 - Iterator
10
[..., drop = F]将始终返回一个数据框。 - hadley
3
这是特别好知道的,因为 df$x 语法返回一个向量。我使用这个语法很长时间,但当我不得不开始使用 df['name']df[n] 来检索列时,当我试图将它们发送到期望向量的函数时,遇到了问题。使用 df[[n]]df[['x']] 就可以解决问题。 - jimjamslam
11
为什么as.vector函数似乎没有任何效果却没有提示错误?它不是应该返回一个向量或者明显地失败吗? - bli
1
aframe[['a2']]sf 对象中非常有用,因为 aframe[,"a2"] 将返回两列,因为几何列也被包括在内。 - Matt

82

现在有一种使用dplyr的简单方法来做到这一点。

dplyr::pull(aframe, a2)

38
你可以使用 $ 提取:
class(aframe$a1)
[1] "numeric"

或者双方括号:

class(aframe[["a1"]])
[1] "numeric"

21

您不需要使用as.vector()函数,但需要正确地进行索引:avector <- aframe[ , "a2"]

还有一件需要注意的事情是在[中使用drop=FALSE选项:

R> aframe <- data.frame(a1=c1:5, a2=6:10, a3=11:15)
R> aframe
  a1 a2 a3
1  1  6 11
2  2  7 12
3  3  8 13
4  4  9 14
5  5 10 15
R> avector <- aframe[, "a2"]
R> avector
[1]  6  7  8  9 10
R> avector <- aframe[, "a2", drop=FALSE]
R> avector
  a2
1  6
2  7
3  8
4  9
5 10
R> 

4
"drop=FALSE" 的提示很有用 - 它有助于我在从数据框中选择 N 列的情况下进行操作,特别是当 N=1 时。 - Iterator
当我无法预见所选列的数量时,我会使用这个函数。即使只选择了一列,结果仍将作为具有n列的数据框传递。向量可能会在后续函数中引发问题。 - Roman Luštrik

17

你可以试试这样的做法-

as.vector(unlist(aframe$a2))

如果您想使用“identical”比较两列,那么这很好。 - p-robot
如果您事先不知道列名,这也很有帮助...即 as.vector(unlist(aframe[,1])) - shwan

14

使用'[['运算符的另一个优点是它可用于 data.frame 和 data.table。因此,如果函数必须同时运行于 data.frame 和 data.table,并且您想要将其中一列作为向量提取,则可以使用'[['。

data[["column_name"]] 

是最好的。


简单!谢谢! - amc

11
as.vector(unlist(aframe['a2']))

6
a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)
avector <- as.vector(aframe['a2'])

avector<-unlist(avector)
#this will return a vector of type "integer"

5
如果您只使用提取运算符,它将起作用。默认情况下,[]设置选项drop=TRUE,这是您此处想要的。有关更多详细信息,请参见?'['
>  a1 = c(1, 2, 3, 4, 5)
>  a2 = c(6, 7, 8, 9, 10)
>  a3 = c(11, 12, 13, 14, 15)
>  aframe = data.frame(a1, a2, a3)
> aframe[,'a2']
[1]  6  7  8  9 10
> class(aframe[,'a2'])
[1] "numeric"

2

我们还可以将数据框列通用地转换为简单向量。 as.vector 不够,因为它保留了数据框的类和结构,所以我们还必须提取第一个(也是唯一的)元素:

df_column_object <- aframe[,2]
simple_column <- df_column_object[[1]]

到目前为止,所有建议的解决方案都需要硬编码列标题。这使它们不是通用的(想象一下将其应用于函数参数)。

或者,您当然可以从列首先读取列名,然后在其他解决方案中将它们插入代码中。


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