【问题标题】:Re-shape status columns based on value in another column根据另一列中的值重塑状态列
【发布时间】:2018-12-11 11:52:47
【问题描述】:

我有一个如下所示的表格:

ID    Start_year    Status_2005    Status_2006    Status_2007
 1          2005            GBR            GBR            FRA
 2          2006             NA            FRA            FRA
 3          2007             NA             NA            GBR
 4          2006             NA            UKR            RUS

我想重新塑造数据,以便它给出开始年份之后年份的状态。所以上面的内容看起来像这样:

ID     Year_0    Year_1    Year_2
 1        GBR       GBR       GBR
 2        FRA       FRA        NA
 3        GBR        NA        NA
 4        UKR       RUS        NA

我一直在尝试在 R 中使用 tidyverse,将收集与“starts_with”结合使用,并进行变异以创建新列。但是,我一直以“years_since_start_year”的单列结束,并且无法弄清楚如何扩展此列来制作我的决赛桌。

非常感谢任何帮助

【问题讨论】:

    标签: r dataframe dplyr tidyverse


    【解决方案1】:

    这是一个 data.table 方法:

    library(data.table)
    setDT(df)
    df <- melt(df, id.vars = c("ID", "Start_year"))   # melt to long format
    df <- df[!is.na(value)]                           # remove NA entries
    df[, year := seq_len(.N) -1L, by = ID]            # add year-number
    dcast(df, ID ~ year, value.var = "value")         # reshape to wide format
    #      ID      0      1      2
    #1:     1    GBR    GBR    FRA
    #2:     2    FRA    FRA   <NA>
    #3:     3    GBR   <NA>   <NA>
    #4:     4    UKR    RUS   <NA>
    

    【讨论】:

      【解决方案2】:

      这就是我使用 tidyverse 的方式

      library(tidyverse)
      
      # create data
      df_raw <- data.frame(ID = c(1:4), 
                       Start_year = c(2005,2006,2007,2006),
                       Status_2005 =c("GBR", NA, NA, NA),
                       Status_2006 =c("GBR", "FRA", NA, "UKR"),
                       Status_2007 =c("FRA", "FRA", "GBR", "RUS"),
                       stringsAsFactors = F)
      
      
      
      df <- df_raw %>% 
        gather(starts_with("Status"), key = Key, value = Value ) %>% 
        arrange(ID) %>% 
        drop_na(Value) %>% 
        mutate(cnt = unlist(map(rle(ID)$lengths-1, seq, from = 0, by =1 ))) %>% 
        mutate(Key = paste0("Year_", cnt)) %>% 
        select(-Start_year, -cnt) %>% 
        spread(key = Key, value = Value)
      
      df
      #>   ID Year_0 Year_1 Year_2
      #> 1  1    GBR    GBR    FRA
      #> 2  2    FRA    FRA   <NA>
      #> 3  3    GBR   <NA>   <NA>
      #> 4  4    UKR    RUS   <NA>
      

      【讨论】:

        【解决方案3】:

        这是一些粗略的基础R + dplyr

        df %>%
          select(starts_with("Status")) %>%
          apply(1, function(x) {x <- x[!is.na(x)]; length(x) <- 3; x}) %>%
          t() %>%
          as.data.frame() %>%
          cbind(df[["ID"]], .) %>%
          setNames(c("ID", paste0("Year_", 1:3)))
        
          ID Year_1 Year_2 Year_3
        1  1    GBR    GBR    FRA
        2  2    FRA    FRA   <NA>
        3  3    GBR   <NA>   <NA>
        4  4    UKR    RUS   <NA>
        

        Tidyverse 风格:

        library(tidyr)
        library(dplyr)
        df %>%
          select(-Start_year) %>%
          gather(key = "year", value = "country", -ID) %>%
          filter(!is.na(country)) %>%
          group_by(ID) %>%
          mutate(year = paste0("year_", 1:length(year))) %>%
          spread(key = "year", value = "country")
        
        # A tibble: 4 x 4
        # Groups:   ID [4]
             ID year_1 year_2 year_3
          <int> <chr>  <chr>  <chr> 
        1     1 GBR    GBR    FRA   
        2     2 FRA    FRA    NA    
        3     3 GBR    NA     NA    
        4     4 UKR    RUS    NA   
        

        【讨论】:

          猜你喜欢
          • 2022-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-03
          • 2019-09-14
          • 1970-01-01
          • 2022-12-15
          • 1970-01-01
          相关资源
          最近更新 更多