将数据框的一行转换为向量

157

我想从数据框的一行中创建一个向量,但不想要行和列名。我尝试了几种方法... 但没有成功。

这是我的数据框:

> df <- data.frame(a=c(1,2,4,2),b=c(2,6,2,1),c=c(2.6,8.2,7.5,3))
> df
  a b   c
1 1 2 2.6
2 2 6 8.2
3 4 2 7.5
4 2 1 3.0

我尝试了:

> newV <- as.vector(df[1,])
> newV
  a b   c
1 1 2 2.6

但我真的想要像这样看起来的东西:

> newV <- c( 1,2,2.6)
> newV
[1] 1.0 2.0 2.6

我建议您正确地格式化所展示的数据。看起来您缺少了一些换行符。 - CHP
我想要一行。是第一行而不是第一列。 - Joko
有没有一种方法可以将此应用于数据框的所有行,从而将所有向量合并为单个向量? - stephanmg
2
@stephanmg:这样的东西怎么样:c(t(as.matrix(df))) - Andri Signorell
安德烈:那样是可行的,不过我也可以用不同的方法解决它。 - stephanmg
6个回答

213

当你从数据框中提取单行数据时,你会得到一个只有一个行的数据框。将其转换为数值向量:

as.numeric(df[1,])

如@Roland所建议的那样,unlist(df[1,])将把一行数据框转换为数值向量而不会丢弃名称。因此,unname(unlist(df[1,]))是另一种稍微更明确的方法来获得相同的结果。

如@Josh在下面评论的,如果您有一个非完全数值(字母,因子,混合...)的数据框,则需要使用as.character(df[1,])


as.numeric() 返回的向量大小比 unlist() 返回的要小得多。例如,as.numeric(df[1, ]) 的大小为 72 字节,而 unlist(df[1, ]) 的大小为 400 字节。 - semibruin
@semibruin,差别在于是否保留名称。请尝试 object.size(unname(unlist(df[1,]))) - Ben Bolker
2
需要注意的是,数据框已经是一个向量,因此as.vector将其视为“列表”模式的向量并不做任何操作。为了便于理解底层机制,请尝试使用更具说明性的as.vector(df [1,],mode =“numeric”)。这就是as.numeric的作用。 - user4256874
1
没有问题。我只是在说,对于这个问题,它们给出了完全相同的答案。 - Ben Bolker
1
可能在此期间已经发生了变化,但今天的unlist允许删除名称:identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,]))(顺便说一下,df仍然不是一个合理的数据框名称... ;-)) - Andri Signorell
显示剩余9条评论

59

我建议使用unlist函数,它可以保留名称。

unlist(df[1,])
  a   b   c 
1.0 2.0 2.6 

is.vector(unlist(df[1,]))
[1] TRUE

如果您不想要一个命名向量:

unname(unlist(df[1,]))
[1] 1.0 2.0 2.6

15

这里有一个基于dplyr的选项:

newV = df %>% slice(1) %>% unlist(use.names = FALSE)

# or slightly different:
newV = df %>% slice(1) %>% unlist() %>% unname()

8
如果您不想转换为数字,可以尝试这个方法。
> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6

3
这句话对我来说没有太多意义:str(as.vector(t(df)[,1]))num [1:3] 1 2 2.6,也就是说,你的代码确实将结果转换为数字向量... - Ben Bolker
2
具体地说,当你使用 t(df) 时,R会将数据框强制转换为一个矩阵,在这种情况下是一个数值矩阵,因为所有元素都是数值。然后 [,1] 提取第一列(一个数值向量,因为多余的维度会自动删除)。as.vector() 只是删除了名称(你也可以使用 unname() 来做同样的操作)。 - Ben Bolker
它似乎也适用于字符。但是你关于强制转换的想法是正确的。顺便说一下,我的解决方案也适用于字符数据框架...但需要注意的是所有数据都将被转换为字符。 - CHP
2
我认为 unname(unlist(x)) 的解决方案更好一些(更高效、更透明)。 - Ben Bolker
as.vector(t(df)[,1]) 我喜欢它!正是我所需要的! - Uther Pendragon
如果一个列是“factor”,则使用unlist将其转换为索引。 - user3226167

5
请注意,如果您的行包含因子,则必须小心。以下是一个例子:
df_1 = data.frame(V1 = factor(11:15),
                  V2 = 21:25)
df_1[1,] %>% as.numeric() # you expect 11 21 but it returns 
[1] 1 21

这里是另一个例子(默认情况下,data.frame()会将字符转换为因子)

df_2 = data.frame(V1 = letters[1:5],
                  V2 = 1:5)
df_2[3,] %>% as.numeric() # you expect to obtain c 3 but it returns
[1] 3 3
df_2[3,] %>% as.character() # this won't work neither
[1] "3" "3"

为了防止这种行为,您需要在提取因素之前注意因素:
df_1$V1 = df_1$V1 %>% as.character() %>% as.numeric()
df_2$V1 = df_2$V1 %>% as.character()
df_1[1,] %>% as.numeric()
[1] 11  21
df_2[3,] %>% as.character()
[1] "c" "3"

-6

数据框的列已经是向量,你只需要将它们提取出来。请注意,在逗号后面放置你想要的列,而不是在前面:

> newV <- df[,1]
> newV
[1] 1 2 4 2

如果你真的想要一行,那就按照Ben所说的去做,并且将来请正确使用单词。

1
但我认为OP想要第一行? - Ben Bolker
1
@BenBolker 也许是这样...我只是假设他想要他的标题和问题所说的东西。 - Jonathan Christensen

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