【问题标题】:Append the dataset with data in certain columns将数据集附加到某些列中的数据
【发布时间】:2020-05-05 22:17:42
【问题描述】:

如果这是我的测试数据集

    Id    Col1_ABC   Col2_BCD    Col3_CBD     Col1_ABC_1    Col2_BCD_1    Col3_CBD_1
    1     Yes        No          No           Yes           Yes           No
    2     No         No          No           Yes           No            Yes
    3     Yes        Yes         Yes          No            Yes           No
    4     Yes        No          Yes
    5     No         No          No

我喜欢将带有尾随 _1 的列中的数据移到数据下方没有尾随 _1 。最终的数据集应该是这样的

    Id    Col1_ABC   Col2_BCD    Col3_CBD   Status   
    1     Yes        No          No         Pre  
    2     No         No          No         Pre  
    3     Yes        Yes         Yes        Pre  
    4     Yes        No          Yes        Pre
    5     No         No          No         Pre

    1     Yes        Yes         No         Post
    2     Yes        No          Yes        Post
    3     No         Yes         No         Post

我知道一种非常笨拙的方法来执行此操作,其中涉及子设置、重命名和执行 rbind,但我正在寻找一种更有效的方法,非常感谢任何建议。

【问题讨论】:

    标签: r transform


    【解决方案1】:

    在修改不以rename_at结尾的列名后,我们可以使用tidyr中的pivot_longer将列从“宽”重塑为“长”

    library(dplyr)
    library(tidyr)
    library(stringr)
    df1 %>%
        rename_at(-1, ~ str_replace(., '([A-Z])$', '\\1_0')) %>% 
        pivot_longer(cols = -Id, names_to = c( ".value", "Status"),
             names_sep = "_(?=[0-9])", values_drop_na = TRUE) %>%
        mutate(Status = factor(Status, levels = 0:1, labels = c("Pre", "Post"))) %>%
        arrange(Status) 
    #   Id Status Col1_ABC Col2_BCD Col3_CBD
    #1  1    Pre      Yes       No       No
    #2  2    Pre       No       No       No
    #3  3    Pre      Yes      Yes      Yes
    #4  4    Pre      Yes       No      Yes
    #5  5    Pre       No       No       No
    #6  1   Post      Yes      Yes       No
    #7  2   Post      Yes       No      Yes
    #8  3   Post       No      Yes       No
    

    或者另一种选择是 data.table 中的 melt,我们在 measure 中指定 patterns 以将数据从“宽”格式转换为“长”格式

    library(data.table)
    melt(setDT(df1), measure = patterns("Col1_ABC", "Col2_BCD", "Col3_CBD"), 
        na.rm = TRUE, variable.name = 'Status',
       value.name = c("Col1_ABC", "Col2_BCD", "Col3_CBD"))[,
             Status := c("Pre", "Post")[Status]][]
    #   Id Status Col1_ABC Col2_BCD Col3_CBD
    #1:  1    Pre      Yes       No       No
    #2:  2    Pre       No       No       No
    #3:  3    Pre      Yes      Yes      Yes
    #4:  4    Pre      Yes       No      Yes
    #5:  5    Pre       No       No       No
    #6:  1   Post      Yes      Yes       No
    #7:  2   Post      Yes       No      Yes
    #8:  3   Post       No      Yes       No
    

    数据

    df1 <- structure(list(Id = 1:5, Col1_ABC = c("Yes", "No", "Yes", "Yes", 
    "No"), Col2_BCD = c("No", "No", "Yes", "No", "No"), Col3_CBD = c("No", 
    "No", "Yes", "Yes", "No"), Col1_ABC_1 = c("Yes", "Yes", "No", 
    NA, NA), Col2_BCD_1 = c("Yes", "No", "Yes", NA, NA), Col3_CBD_1 = c("No", 
    "Yes", "No", NA, NA)), class = "data.frame", row.names = c(NA, 
    -5L))
    

    【讨论】:

    • @akurn,为什么说,Error in pivot_longer(., cols = -Id, names_to = c(".value", "Status"), : could not find function "pivot_longer"
    • @JimmySanders。你加载了library(tidyr)。我用packageVersion('tidyr')# [1] ‘1.0.0’
    • @akurn,在我的环境中看起来有些包冲突。
    • @JimmySanders 你能用这些包在一个新的会话中加载它吗? tidyr 版本很重要,因为这是在 1.0.0 中引入的
    • 感谢 data.table 版本的工作,我有一个旧的 0.8 版本的 tidyr。所以我有一些工作要做。
    【解决方案2】:

    涉及dplyrtidyr的另一个选项可能是:

    df %>%
     pivot_longer(-Id) %>%
     mutate(Status = if_else(grepl("_1", name, fixed = TRUE), "Post", "Pre"),
            name = gsub("^([^_]*_[^_]*)_.*$", "\\1", name)) %>%
     pivot_wider(names_from = "name", values_from = "value") %>%
     filter_all(all_vars(!is.na(.))) %>%
     arrange(Status)
    
         Id Status Col1_ABC Col2_BCD Col3_CBD
      <int> <chr>  <chr>    <chr>    <chr>   
    1     1 Post   Yes      Yes      No      
    2     2 Post   Yes      No       Yes     
    3     3 Post   No       Yes      No      
    4     1 Pre    Yes      No       No      
    5     2 Pre    No       No       No      
    6     3 Pre    Yes      Yes      Yes     
    7     4 Pre    Yes      No       Yes     
    8     5 Pre    No       No       No 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 2012-03-23
      • 2022-10-06
      • 2016-03-20
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多