代码之家  ›  专栏  ›  技术社区  ›  Andrew Scotchmer

列值作为列名并用其他列值填充

  •  2
  • Andrew Scotchmer  · 技术社区  · 1 年前

    我的表格如下:

    df <- data.table(ID = c(1,2,3,1,2,1,1,2,3),
                     vlaue = c("A", "B", "C", "A", "B", "A", "A", "B", "C"))
    
    > df
          ID vlaue
      1:  1     A
      2:  2     B
      3:  3     C
      4:  1     A
      5:  2     B
      6:  1     A
      7:  1     A
      8:  2     B
      9:  3     C
    

    我需要从中创建第二个表,其中列是唯一的ID值,行是相应的值列,

    > df2
         1 2 3
      1: A B C
      2: A B  
      3: A    
      4: A B C
    

    我试着重塑,dcast,玩矩阵,但没有什么能产生我想要的表格。

    2 回复  |  直到 1 年前
        1
  •  3
  •   Maël    1 年前

    在里面 data.table :

    library(data.table)
    dcast(df[, gp := cumsum(ID == 1)], gp ~ ID, value.var = 'vlaue')
    #    gp 1    2    3
    # 1:  1 A    B    C
    # 2:  2 A    B <NA>
    # 3:  3 A <NA> <NA>
    # 4:  4 A    B    C
    

    在里面 dplyr :

    library(tidyr)
    library(dplyr)
    
    df %>% 
      mutate(gp = cumsum(ID == 1)) %>% 
      pivot_wider(names_from = "ID", values_from = "vlaue") %>% 
      select(-gp)
    
        2
  •  1
  •   ThomasIsCoding    1 年前

    对于 data.table

    如果 df 已经是 数据表 对象,我们可以使用 dcast 如下所示

    > dcast(df, rowid(ID) ~ ID, value.var = "vlaue")[, -1]
       1    2    3
    1: A    B    C
    2: A    B    C
    3: A    B <NA>
    4: A <NA> <NA>
    

    对于 data.frame

    如果 df 数据帧 (而不是 数据表 ),你可以试试 dplyr approach by @Maël ,或基本R选项 reshape

    reshape(
      transform(
        df,
        row = ave(ID, ID, FUN = seq_along)
      ),
      direction = "wide",
      idvar = "row",
      timevar = "ID"
    )[-1]
    

    它给出

      vlaue.1 vlaue.2 vlaue.3
    1       A       B       C
    4       A       B       C
    6       A       B    <NA>
    7       A    <NA>    <NA>