首页 文章

R宽到长整形与列名称

提问于
浏览
1

我有这种格式的数据

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 回答

  • 3

    我们可以将 gather 转换为'long'格式,然后 separate 将'key'列分成两个,在数字部分之前拆分, spread 将它改为'wide'并将'key1'列更改为行名称

    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
    

    数据

    df1 <- structure(list(A1 = 10L, A2 = 5L, B1 = 11L, B2 = 5L, C1 = 21L, 
         C2 = 10L), class = "data.frame", row.names = c(NA, -1L))
    
  • 1

    问题的标签是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) reshape 另一个基本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

    一个 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
    

相关问题