使用R将行转换为列,列转换为行

29

我有一个数据框,其中行名和列名都是唯一的。我想将行转换为列,并将列转换为行。

例如,以下代码:

starting_df <- data.frame(row.names= c(LETTERS[1:4]),
                          a = c(1:4),
                          b = seq(0.02,0.08,by=0.02),
                          c = c("Aaaa","Bbbb","Cccc","Dddd")
                )

导致如下结果:

> starting_df
  a    b    c
A 1 0.02 Aaaa
B 2 0.04 Bbbb
C 3 0.06 Cccc
D 4 0.08 Dddd

我希望将它转换为另一个数据框,该数据框包含完全相同的数据,只是以前是行现在是列,反之亦然:

> final_df
     A    B    C    D
a    1    2    3    4
b 0.02 0.04 0.06 0.08
c Aaaa Bbbb Cccc Dddd

2
我本可以用其他语言完成这个任务,但我确信在 R 中有一种快速的方法可以做到。当我意识到答案时,我感到非常愚蠢,但我认为这对于任何试图弄清楚它的人都会很有用。顺便说一句,我使用了 [r] 标签在 Stackoverflow 上搜索了许多以下变体:将行转换为列,反之亦然;将列转换为行和行转换为列;旋转数据框;交换行和列; - Christopher Bottoms
2个回答

54

只需使用基本的转置函数t,并用as.data.frame包装:

final_df <- as.data.frame(t(starting_df))
final_df
     A    B    C    D
a    1    2    3    4
b 0.02 0.04 0.06 0.08
c Aaaa Bbbb Cccc Dddd

已更新。正如docendo discimus所指出的,t返回一个矩阵。正如Mark建议的那样,将其包装在as.data.frame中,可以得到一个数据框而不是矩阵。谢谢!


1
通过转置数据框,您已经“秘密地”将其转换为矩阵类:class(final_df) # [1] "matrix" - talat
1
将其包装在 as.data.frame() 中以确保它是一个 data.frame。 - Mark
2
@Mark,如果你的列具有不同的类别,那么将其转换为矩阵可能会产生一些副作用,因为在R中的矩阵只能具有相同类别的列。 - talat
@docendodiscimus 很好的观点 - 我通常会等到问题真正影响到我时才会解决。不过,在这种情况下,为了让转置有意义,所有行都必须是相同的类。 - Mark

6

以下是一个可能依据数据能起到作用的 tidyverse 选项,以及其使用的一些注意事项:

library(tidyverse)

starting_df %>% 
  rownames_to_column() %>% 
  gather(variable, value, -rowname) %>% 
  spread(rowname, value)

rownames_to_column()函数在原数据框具有有意义的行名时是必需的,否则新转置的数据框中的新列名将是对应于原始行数的整数。如果没有有意义的行名,则可以跳过rownames_to_column()并用数据框中第一列的名称替换rowname,假设这些值是唯一且有意义的。使用tidyr::smiths示例数据如下:

smiths %>% 
    gather(variable, value, -subject) %>% 
    spread(subject, value)

使用“tidyverse”方法的示例“starting_df”将会提示有关删除属性的警告信息。这与将具有不同属性类型的列转换为单个字符列有关。“smiths”数据没有发出该警告,因为除了“subject”列之外,所有列都是双精度浮点数。
使用“as.data.frame(t())”的早期答案将会将所有内容转换为因子,如果混合列类型,除非添加了“stringsAsFactors = FALSE”,而“tidyverse”选项则默认将所有内容转换为字符,如果存在混合列类型,则会将其全部转换为字符。

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