如何通过保留 header 名称来转置 table

How to transpose the table by keeping the header names

我简化了我之前的问题。不便之处敬请原谅。 如何通过保留 header 名称来转置 table。我也无法通过使用 t() 来实现。

q <- tribble(
  ~name, ~g1, ~g2, ~g3,
  "t1", 0,  1,  2,
  "t1", 2,  2,  2,
  "t2", 1,  2,  3,
  "t2", 3,  3,  3,
  "t4", 4,  4,  4
)


q %>%
  rownames_to_column %>% 
  gather(row, value, -rowname) %>% 
  spread(rowname, value) 

期望的输出

name    t1    t1    t2    t2    t4
g1     0     2     1     3     4
g2     1     2     2     3     4
g3     2     2     3     3     4

如果您想使用 tidyr 包中的 spread 创建 "t#" 命名列,请注意它是按字母顺序进行的,并且不能很好地处理重复的列名字。

您的示例有两行名为 "t1" 和两行名为 "t2"。所以需要处理。

名称 在此示例中按字母顺序排列 ,但假设情况并非总是如此,您可以在名称前加上一系列数字 运行订单。

可以修改类似以下的内容来工作:

qt <- q %>%
  # make row names unique & sorted correctly in increasing order
  # by appending numbers in running order
  mutate(name = paste(seq(1, n()),
                      name,
                      sep = "_")) %>%
  gather(row, value, -name) %>% 
  spread(name, value)

# strip away the appended numbers from the newly created column names
names(qt) <- sapply(strsplit(names(qt), "_"), function(x){x[2]})

> qt
# A tibble: 3 x 6
   `NA`    t1    t1    t2    t2    t4
* <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1    g1     0     2     1     3     4
2    g2     1     2     2     3     4
3    g3     2     2     3     3     4

或者,如果您不需要 tidyverse 解决方案:

# transpose the data frame without the name column
qt <- t(q[-1]) 

# add name column back as a dimname attribute
attr(qt, "dimnames")[[2]] <- unname(unlist(q[1]))
# edit: alternative to above
colnames(qt) <- q[1][[1]]

# convert result to data frame
qt <- as.data.frame(qt)

> qt
   t1 t1 t2 t2 t4
g1  0  2  1  3  4
g2  1  2  2  3  4
g3  2  2  3  3  4

无论如何,我希望这是为了展示而不是分析,因为在 tidyverse 中使用重复的列名真的很难。