【问题标题】:from wide format to long format with results in multiple columns [duplicate]从宽格式到长格式,结果在多列中[重复]
【发布时间】:2015-11-24 16:30:27
【问题描述】:

我有一个类似于以下数据框的数据,但每个组合都有大约十个字段,从 name1、adress1、city1 等开始

   id name1  adress1 name2  adress2  name3  adress3
1  1  John street a  Burt street d  chris street 1
2  2  Jack street b   Ben street e connor street 2
3  3  Joey     <NA>   Bob street f   <NA>     <NA>  

现在我想重新排列这些数据,让它更有用一点,它应该看起来像这样,但带有它来自哪个条目的信息:

      id origin  names adresses
1  1      1   John street a
2  2      1   Jack street b
3  3      1   Joey     <NA>
4  1      2   Burt street d
5  2      2    Ben street e
6  3      2    Bob street f
7  1      3  chris street 1
8  2      3 connor street 2     

使用 tidyr 我可以获得长格式,但是我有一个包含所有变量名称的键列,name1、name2、name3、street1 等。

我还尝试使用单独的数据框,每个组合一个,例如一个数据框用于名称,一个用于街道等。但是将所有内容重新组合在一起会导致错误的记录,因为您只能加入 id 并且以长格式复制此 ID。我也一直在研究 Reshape2,但这会导致同样的问题。

我见过的所有从宽到长的转换都是当您有一个要转换到的列时。我正在寻找 10 列中的最终结果,或者如示例中的 2 列。

有没有我忽略的功能?

#code to generete the dataframes:
df <- data.frame(id = c(1,2,3), 
                 name1 = c("John", "Jack", "Joey"), 
                 adress1 = c("street a", "street b", NA), 
                 name2 = c("Burt", "Ben", "Bob"),
                 adress2 = c("street d", "street e", "street f"),
                 name3 = c("chris", "connor", NA),
                 adress3 = c("street 1", "street 2", NA),
                 stringsAsFactors = FALSE)


expecteddf <- data.frame(id = c(1,2,3,1,2,3,1,2), 
                         origin = c(rep(1, 3), rep(2, 3), rep(3, 2)), 
                         names = c("John", "Jack", "Joey", "Burt", "Ben", "Bob", "chris", "connor"), 
                         adresses = c("street a", "street b", NA, "street d", "street e", "street f", "street 1", "street 2"),
                         stringsAsFactors = FALSE


                   )

【问题讨论】:

    标签: r reshape2 tidyr


    【解决方案1】:

    我们可以使用devel 版本的data.table 中的melt,它可以为measure 列使用多个patterns。 'data.table' 的开发版安装说明是here

    我们将 'data.frame' 转换为 'data.table' (setDT(df))、melt,并在measure 参数的patterns 中指定regex。删除 'names' 和 'address' 列的 NA 行。

    library(data.table)#v1.9.5+
    dM <- melt(setDT(df), measure=patterns(c('^name', '^adress')),
              value.name=c('names', 'address') )
    dM[!(is.na(names) & is.na(address))]
    # id variable  names  address
    #1:  1        1   John street a
    #2:  2        1   Jack street b
    #3:  3        1   Joey       NA
    #4:  1        2   Burt street d
    #5:  2        2    Ben street e
    #6:  3        2    Bob street f
    #7:  1        3  chris street 1
    #8:  2        3 connor street 2
    

    或者我们可以使用base R中的reshape

     dM2 <- reshape(df, idvar='id', varying=list(grep('name', names(df)), 
                 grep('adress', names(df))), direction='long')
    

    在我们使用is.na 创建逻辑索引后,可以使用标准的“data.frame”索引删除NA 行,就像在data.table 解决方案中一样。

    【讨论】:

    • 两者都具有魅力。看来我必须更深入地研究 data.table 包,看看里面隐藏着什么其他宝石。
    • @phiver 很高兴知道它有效。您应该查看开发版本,因为它引入了一些新功能。
    猜你喜欢
    • 1970-01-01
    • 2021-09-18
    • 2020-05-18
    • 2015-08-04
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    相关资源
    最近更新 更多