我想从数据框的一行中创建一个向量。但我不想有行和列的名称。我尝试了几件事......但没有运气。
这是我的数据框:
> 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
c(t(as.matrix(df)))
这样的东西呢?
当您从数据框中提取单行时,您会得到一个单行数据框。将其转换为数值向量:
as.numeric(df[1,])
正如@Roland 建议的那样,unlist(df[1,])
会将单行数据帧转换为数字向量,而不会删除名称。因此,unname(unlist(df[1,]))
是获得相同结果的另一种更明确的方法。
正如下面的@Josh 评论,如果您有一个不完全数字(字母、因子、混合...)的数据框,则需要 as.character(df[1,])
代替。
我推荐 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
这是一个基于 dplyr
的选项:
newV = df %>% slice(1) %>% unlist(use.names = FALSE)
# or slightly different:
newV = df %>% slice(1) %>% unlist() %>% unname()
如果您不想更改为数字,可以试试这个。
> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6
str(as.vector(t(df)[,1]))
是 num [1:3] 1 2 2.6
,即您的代码确实将结果转换为数字向量 ...
t(df)
时,R 将数据框强制转换为矩阵,在本例中为数字矩阵,因为所有元素都是数字。然后 [,1]
提取第一列(一个数字向量,因为冗余维度被自动删除)。 as.vector()
只是删除名称(您也可以使用 unname()
来完成)。
unname(unlist(x))
解决方案要好一些(更高效、更透明)。
as.vector(t(df)[,1])
我喜欢它!正是我需要的!
请注意,如果您的行包含一个因子,则必须小心。这是一个例子:
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"
数据框的列已经是向量,你只需要把它们拉出来。请注意,您将所需的列放在逗号之后,而不是之前:
> newV <- df[,1]
> newV
[1] 1 2 4 2
如果你真的想要排,那么就按照 Ben 说的做,以后请正确使用单词。
不定期副业成功案例分享
identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,]))
(顺便说一句 df 仍然不是 data.frame 的明智名称... ;-))