R宽到长整形并带有列名

时间:2018-12-11 15:00:16

标签: r reshape reshape2

我有这种格式的数据

A1 A2 B1 B2  C1  C2
10  5 11  5  21  10

我想将其转换为:

  1  2
A 10 5
B 11 5
C 21 10

如何在R中做到这一点?

3 个答案:

答案 0 :(得分:3)

我们可以将gather转换为'long'格式,然后通过将数字部分separate拆分为'wide'并将{ key1'列到行名

spread

数据

library(tidyverse)
gather(df1) %>%
    separate(key, into = c('key1', 'key2'), sep="(?=\\d)") %>% 
    spread(key2, value) %>% 
    column_to_rownames('key1')
#  1  2
#A 10  5
#B 11  5
#C 21 10

答案 1 :(得分:2)

该问题的标签为r,reshape和reshape2,因此我们将使用其中的每个解决方案进行展示。

1)xtabs 以下是基本的R解决方案。

let <- gsub("\\d", "", names(DF))
num <- gsub("\\D", "", names(DF))
tab <- xtabs(unlist(DF) ~ let + num)

给予:

> tab
   num
let  1  2
  A 10  5
  B 11  5
  C 21 10

或对于数据框:

cbind(let = rownames(tab), as.data.frame.matrix(tab))

给予:

  let  1  2
A   A 10  5
B   B 11  5
C   C 21 10

2)重塑以下是另一个基本的R解决方案。 letnum来自上方。

varying <- split(names(DF), num)
reshape(DF, dir = "long", varying = varying, v.names = names(varying),
  times = unique(let), timevar = "let")[-4]

给予:

    let  1  2
1.A   A 10  5
1.B   B 11  5
1.C   C 21 10

3)reshape2 从上方使用letnum

library(reshape2)

dcast(let ~ num, data = data.frame(value = unlist(DF)), value.var = "value")

给予:

  let  1  2
1   A 10  5
2   B 11  5
3   C 21 10

注意

可复制形式的输入:

Lines <- "
A1 A2 B1 B2  C1  C2
10  5 11  5  21  10"
DF <- read.table(text = Lines, header = TRUE)

答案 2 :(得分:1)

一种data.table解决方案:

library(data.table)
library(magrittr)
melt(df1, measure.vars = names(df1)) %>%
  .[, c("l", "n") := tstrsplit(variable, "")] %>%
  dcast(l ~ n)

   l  1  2
1: A 10  5
2: B 11  5
3: C 21 10