【问题标题】:Spread (tidyr) - Spreading repeated values传播 (tidyr) - 传播重复值
【发布时间】:2016-09-01 14:54:28
【问题描述】:

鉴于此数据:

x <- c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4) 
y <- c('Name', 'Street', 'Gender', 'Name', 'Street', 'Name', 'Street', 'Street', 'Dateofbirth', 'Gender','Name') 
z <- c('Jasper', 'Broadway', 'Male', 'Alice', 'Narrowstreet', 'Peter', 'Neverland', 'Treasureisland', '1841', 'Male','Martin')

k <- data.frame(id = x, key = y, value = z)

我想创建一个干净的 4 列表,其中包含键作为标题(即姓名、街道、性别和出生日期)。这里的问题是关键的“街道”对于彼得来说是双倍的。我试过使用传播(tidyr),但我没有设法让它工作。

k <- k %>% group_by(id) %>%
           mutate(index = row_number()) %>%
           spread(key, value)

我也试了一下:

k <- k %>% group_by(id) %>%
  mutate(index = row_number()) %>%
  spread(id, value) 

结果不是我所期望的,这两个表都很难使用。有什么想法吗?

【问题讨论】:

  • 不清楚你想用这些加倍的值做什么......一个选项(使用reshape2而不是tidyr)看起来像dcast(k, id ~ key, fun=toString)
  • 好点。理想情况下,我想保留它们并将它们插入单独的列中。作为第二好的选择,我可以保留第一个。如果你觉得问题不够清楚,我会修改。
  • 是的,我认为编辑它会很好。在我看来,列出这两个选项很好。
  • 刚刚尝试过,它可以工作!您可以将其发布为答案。干杯!
  • 当然。顺便说一句,除了编辑您的问题以包含您上次评论中的信息之外,我认为您应该改进标题(“传播重复值”之类的?)

标签: r dplyr tidyr


【解决方案1】:

不知道这是否正是您要找的,但如果您只想保留第一个,您可以使用first group_by(id,key)summarise value。然后,由idspread 重新组合:

library(dplyr)
library(tidyr)
k <- k %>% group_by(id, key) %>% summarise(value=first(value)) %>% group_by(id) %>% spread(key,value)    
##Source: local data frame [4 x 5]
##Groups: id [4]
##
##     id Dateofbirth Gender   Name       Street
##* <dbl>      <fctr> <fctr> <fctr>       <fctr>
##1     1          NA   Male Jasper     Broadway
##2     2          NA     NA  Alice Narrowstreet
##3     3        1841   Male  Peter    Neverland
##4     4          NA     NA Martin           NA

要将加倍的值放在不同的列中,请使用 make.names 创建唯一键:

k <- k %>% group_by(id) %>% mutate(key=make.names(key,unique=TRUE)) %>% group_by(id) %>% spread(key,value)
##Source: local data frame [4 x 6]
##Groups: id [4]
##
##     id Dateofbirth Gender   Name       Street       Street.1
##* <dbl>      <fctr> <fctr> <fctr>       <fctr>         <fctr>
##1     1          NA   Male Jasper     Broadway             NA
##2     2          NA     NA  Alice Narrowstreet             NA
##3     3        1841   Male  Peter    Neverland Treasureisland
##4     4          NA     NA Martin           NA             NA

或者,您可以 group_by(id,key)summarise value 使用 toStringpastecollapse 来展平加倍的值:

k <- k %>% group_by(id, key) %>% summarise(value=toString(value)) %>% group_by(id) %>% spread(key,value)
##Source: local data frame [4 x 5]
##Groups: id [4]
##
##     id Dateofbirth Gender   Name                    Street
##* <dbl>       <chr>  <chr>  <chr>                     <chr>
##1     1        <NA>   Male Jasper                  Broadway
##2     2        <NA>   <NA>  Alice              Narrowstreet
##3     3        1841   Male  Peter Neverland, Treasureisland
##4     4        <NA>   <NA> Martin                      <NA>

【讨论】: