【问题标题】:How to transform row to column based on a single row in R?如何基于R中的单行将行转换为列?
【发布时间】:2020-08-18 22:44:01
【问题描述】:

我有一个看起来像这样的数据集

A    B    1960 1970 1980
x    a    1    2    3
x    b    1.1  2.1  NA
y    a    2    3    4
y    b    1    NA   1

我想根据 B 行转换列,使其看起来像这样

A    year       a    b
x    1960    1   1.1    
x    1970    2   2.1
x    1980    3   NA    
y    1960    2   1
y    1970    3   NA
y    1980    4   1

我不知道该怎么做。我知道我可以使用 t() 或使用 tidyverse 中的 row_to_columns() 进行完全转换,但结果不是我想要的。 初始数据大约有 60 列,B 列中有 165 个不同的值。

【问题讨论】:

  • 你能“输入”你的数据吗?
  • d %>% dplyr::pivot_longer(3:5) 和一些列重命名应该可以工作。

标签: r matrix transform data-manipulation data-wrangling


【解决方案1】:
library(data.table)

dt <- fread('A    B    1960 1970 1980
x    a    1    2    3
x    b    1.1  2.1  NA
y    a    2    3    4
y    b    1    NA   1')

names(dt) <- as.character(dt[1,])
dt <- dt[-1,]
dt[,(3:5):=lapply(.SD,as.numeric),.SDcols=3:5]
dcast(melt(dt,measure.vars = 3:5),...~B,value.var = "value")
#>    A variable a   b
#> 1: x     1960 1 1.1
#> 2: x     1970 2 2.1
#> 3: x     1980 3  NA
#> 4: y     1960 2 1.0
#> 5: y     1970 3  NA
#> 6: y     1980 4 1.0

reprex package (v0.3.0) 于 2020-05-05 创建

【讨论】:

    【解决方案2】:

    基础 R 解决方案:

    long_df <- reshape(df, direction = "long", 
            varying = which(!names(df) %in% c("A", "B")),
            v.names = "value",
            timevar = "year",
            times = names(df)[!(names(df) %in% c("A", "B"))],
            ids = NULL,
            new.row.names = 1:(length(which(!names(df) %in% c("A", "B"))) * nrow(df)))
    
    
    wide_df <- setNames(reshape(long_df, direction = "wide", 
                       idvar = c("A", "year"),
                       timevar = "B"), c("A", "B", unique(df$B)))
    

    数据:

    df <- structure(list(A = c("x", "x", "y", "y"), B = c("a", "b", "a", 
    "b"), `1960` = c(1, 1.1, 2, 1), `1970` = c(2, 2.1, 3, NA), `1980` = c(3L, 
    NA, 4L, 1L)), row.names = 2:5, class = "data.frame")
    

    【讨论】:

      【解决方案3】:

      您可以先进行 pivot_long() 然后 pivot_wide() ,但再次重命名您的列“B”可能是个坏主意:

      library(dplyr)
      library(tidyr)
      
      df %>% pivot_longer(-c(A,B)) %>% 
      pivot_wider(names_from=B) %>% rename(B=name)
      
          # A tibble: 6 x 4
        A     B         a     b
        <fct> <chr> <dbl> <dbl>
      1 x     1960      1   1.1
      2 x     1970      2   2.1
      3 x     1980      3  NA  
      4 y     1960      2   1  
      5 y     1970      3  NA  
      6 y     1980      4   1 
      
      df = structure(list(A = structure(c(1L, 1L, 2L, 2L), .Label = c("x", 
      "y"), class = "factor"), B = structure(c(1L, 2L, 1L, 2L), .Label = c("a", 
      "b"), class = "factor"), `1960` = c(1, 1.1, 2, 1), `1970` = c(2, 
      2.1, 3, NA), `1980` = c(3L, NA, 4L, 1L)), class = "data.frame", row.names = c(NA, 
      -4L))
      

      【讨论】:

        猜你喜欢
        • 2011-07-12
        • 2022-10-14
        • 2017-10-06
        • 2021-05-07
        • 2013-12-26
        • 2012-03-08
        • 2015-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多