【问题标题】:r data transform separate columnsr 数据转换单独的列
【发布时间】:2021-01-27 02:00:19
【问题描述】:

我有一个包含两列三列的数据集。第三列有日期值和一些字符串。

 ID     Col1        Value
 123    Start.Date  2011-06-18
 123    Stem        A1
 123    Stem_1      A6
 123    Stem_2      NA
 321    Start.Date  2014-08-05
 321    Stem        C1
 321    Stem_1      C4
 321    Stem_2      NA
 677    Start.Date  NA
 677    Stem        NA
 677    Stem_1      NA
 677    Stem_2      NA

我怎样才能将日期分开并将它们存储在这样的不同列中?

 ID     Col1        Value       Start.Date
 123    Stem        A1          2011-06-18 
 123    Stem_1      A6          2011-06-18
 123    Stem_2      NA          2011-06-18 
 321    Stem        C1          2014-08-05
 321    Stem_1      C4          2014-08-05
 321    Stem_2      NA          2014-08-05
 677    Stem        NA          NA
 677    Stem_1      NA          NA
 677    Stem_2      NA          NA

谢谢。

【问题讨论】:

    标签: r transform reshape dplyr


    【解决方案1】:

    仅基于tidyr 的替代解决方案:

    df %>% pivot_wider(ID, names_from =  Col1, values_from = Value ) %>%
      pivot_longer(c("Stem", "Stem_1", "Stem_2"), names_to = "Col1", values_to = "Value") 
    

    【讨论】:

    • 我收到一条警告消息Warning message: Values are not uniquely identified; output will contain list-cols. * Use values_fn = list` 来禁止此警告。 * 使用 values_fn = length 确定重复出现的位置 * 使用 values_fn = {summary_fun} 总结重复 ` 当我在更大的数据集上尝试这种方法时,结果是带有一些列表值的 goobledegoo
    • @RiloDinga 警告消息是由于特定Col1 值重复导致特定ID 并因此列变为列表列。例如,ID = 999 有两个 Stem_1 值。假设每个ID只有一个Start.Date,那么%>% unnest(cols = c(Start.Date, Value))应该加在最后。
    【解决方案2】:

    在数据中创建一个新列,其值来自 Value 列 wehre Col1 = 'Start.Date'NA 否则。对于每个ID,我们可以填充之前日期的NA 值,并删除带有'Start.Date' 的行。

    library(dplyr)
    library(tidyr)
    
    df %>%
      mutate(Start.Date = as.Date(replace(Value, Col1 != 'Start.Date', NA))) %>%
      group_by(ID) %>%
      fill(Start.Date) %>%
      ungroup() %>%
      filter(Col1 != 'Start.Date')
    
    #    ID Col1   Value Start.Date
    #  <int> <chr>  <chr> <date>    
    #1   123 Stem   A1    2011-06-18
    #2   123 Stem_1 A6    2011-06-18
    #3   123 Stem_2 NA    2011-06-18
    #4   321 Stem   C1    2014-08-05
    #5   321 Stem_1 C4    2014-08-05
    #6   321 Stem_2 NA    2014-08-05
    #7   677 Stem   NA    NA        
    #8   677 Stem_1 NA    NA        
    #9   677 Stem_2 NA    NA        
    

    数据

    df <- structure(list(ID = c(123L, 123L, 123L, 123L, 321L, 321L, 321L, 
    321L, 677L, 677L, 677L, 677L), Col1 = c("Start.Date", "Stem", 
    "Stem_1", "Stem_2", "Start.Date", "Stem", "Stem_1", "Stem_2", 
    "Start.Date", "Stem", "Stem_1", "Stem_2"), Value = c("2011-06-18", 
    "A1", "A6", NA, "2014-08-05", "C1", "C4", NA, NA, NA, NA, NA)), 
    class = "data.frame", row.names = c(NA, -12L))
    

    【讨论】:

    • Ronak Shah,您的解决方案缺少一件事。将日期移动到单独的列后,应删除带有Start.Date 的行。
    • 你说得对,我错过了。我已经更新了答案以包括@RiloDinga
    • 那是完美的。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2021-08-29
    • 1970-01-01
    • 2018-10-21
    • 2013-12-26
    • 1970-01-01
    相关资源
    最近更新 更多