【问题标题】:Rearranging information from data frame in R [duplicate]从R中的数据框中重新排列信息[重复]
【发布时间】:2015-07-07 14:36:01
【问题描述】:

我有以下 df,它是从 excel 文件中获得的:

df1 <- data.frame( Colour = c("Green","Red","Blue"), 
                   Code = c("N","U", "U"), 
                   User1 = c("John","Brad","Peter"), 
                   User2 = c("Meg","Meg","John"), 
                   User3= c("", "Lucy", ""))

我需要重新排列它以获得一个数据框,其中所有名称都列在第一列(仅一次),颜色(和相应的代码)出现在以下列中,如图所示:

df2 <- data.frame(User=c("John","Brad","Peter","Meg","Lucy"),
                  Color1 = c("Green","Red","Blue","Green","Red"),
                  Code1 = c("N","U","U","N","U"), 
                  Color2=c("Blue","","","Red",""),
                  Code2=c("U","","","U",""))

我很感激一些帮助。非常感谢,

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    我们可以使用data.table 的开发版本中的dcast,即v1.9.5+。它可以占用多个value.var 列。我们将data.frame转换为data.table(setDT(df1)),melt将id列为'颜色'和'代码'的数据,删除'用户'不等于''的行([User!=''] ),创建基于“用户”列和dcast 的分组序列。安装说明为here

    library(data.table)#v1.9.5+
    dcast(melt(setDT(df1), id.var=c('Colour', 'Code'), 
               value.name='User')[User!=''][,
                  N:=1:.N, User], User~N, value.var=c('Colour', 'Code'))
    #    User 1_Colour 2_Colour 1_Code 2_Code
    #1:  Brad      Red       NA      U     NA
    #2:  John    Green     Blue      N      U
    #3:  Lucy      Red       NA      U     NA
    #4:   Meg    Green      Red      N      U
    #5: Peter     Blue       NA      U     NA
    

    或者如 cmets 中提到的 @Arun,我们可以在 dcast 中使用 subset 参数而不是 [User!='']

    dcast(melt(setDT(df1), id.var=c('Colour', 'Code'), 
                 value.name='User')[,N:= 1:.N, User],
           subset=.(User !=''), User~N, value.var=c('Colour', 'Code'))
    #    User 1_Colour 2_Colour 1_Code 2_Code
    #1:  Brad      Red       NA      U     NA
    #2:  John    Green     Blue      N      U
    #3:  Lucy      Red       NA      U     NA
    #4:   Meg    Green      Red      N      U
    #5: Peter     Blue       NA      U     NA
    

    【讨论】:

    • 你可以在dcast直接使用subset = .(User != "")
    【解决方案2】:

    由于与@akrun 的答案在概念上相似,我犹豫发布此消息,但您也可以使用我的“splitstackshape”包中的merged.stack 以及base R 中的reshape 来执行此操作。

    library(splitstackshape)
    reshape(
      getanID(
        merged.stack(df1, var.stubs = "User", sep = "var.stubs")[User != ""], 
        "User"), 
      direction = "wide", idvar = "User", timevar = ".id", drop = ".time_1")
    #     User Colour.1 Code.1 Colour.2 Code.2
    # 1: Peter     Blue      U       NA     NA
    # 2:  John     Blue      U    Green      N
    # 3:   Meg    Green      N      Red      U
    # 4:  Brad      Red      U       NA     NA
    # 5:  Lucy      Red      U       NA     NA
    

    merged.stack 使数据变长,getanID 创建一个 ID 变量以在转到宽格式时使用,reshape 执行从半宽格式到宽格式的实际转换。


    对于“dplyr”+“tidyr”用户来说,这是我能想到的最好的方法。看起来很冗长,但应该不难理解:

    library(dplyr)
    library(tidyr)
    
    df1 %>%
      gather(var, User, User1:User3) %>%      # Get the data into a long form
      filter(User != "") %>%                  # Drop empty rows
      group_by(User) %>%                      # Group by User
      mutate(Id = sequence(n())) %>%          # Create a new id variable
      gather(var2, value, Colour, Code) %>%   # Go long a second time
      unite(Key, var2, Id) %>%                # Combine values to create a key
      spread(Key, value, fill = "")           # Convert back to a wide form
    # Source: local data frame [6 x 6]
    # 
    #     var  User Code_1 Code_2 Colour_1 Colour_2
    # 1 User1  Brad      U             Red         
    # 2 User1  John      N           Green         
    # 3 User1 Peter      U            Blue         
    # 4 User2  John             U              Blue
    # 5 User2   Meg      N      U    Green      Red
    # 6 User3  Lucy      U             Red         
    

    【讨论】:

      【解决方案3】:

      这不是很漂亮,但这是纯基础 R 中的另一种解决方案,它使用了几个对 reshape() 的调用:

      reshape(transform(subset(reshape(df1,varying=grep('^User',names(df1)),dir='l',v.names='User'),User!=''),id=NULL,time=ave(c(User),User,FUN=seq_along),User=factor(User)),dir='w',idvar='User',sep='');
      ##      User Colour1 Code1 Colour2 Code2
      ## 1.1  John   Green     N    Blue     U
      ## 2.1  Brad     Red     U    <NA>  <NA>
      ## 3.1 Peter    Blue     U    <NA>  <NA>
      ## 1.2   Meg   Green     N     Red     U
      ## 2.3  Lucy     Red     U    <NA>  <NA>
      

      【讨论】:

        猜你喜欢
        • 2013-07-03
        • 2012-10-01
        • 1970-01-01
        • 2018-07-18
        • 2023-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多