【问题标题】:Create multiple columns in data frame based on another column基于另一列在数据框中创建多列
【发布时间】:2021-04-27 16:10:21
【问题描述】:

我想更新一个数据框以添加 10 列,其中包含基于另一列的值

从这里开始

df <- data.frame(ID = 1:3, name = c("Bob", "Jim", "Fred"), endValue= c(3, 7, 4))

并以此结束

|ID|Name|endValue|A|B|C|D|E|F|G|H|I|J|
|1|Bob|3|Y|Y|Y|N|N|N|N|N|N|N|
|2|Jim|7|Y|Y|Y|Y|Y|Y|Y|N|N|N|
|3|Fred|4|Y|Y|Y|Y|N|N|N|N|N|N|

所以每条新记录需要:

  • 原创内容
  • 十个新列
  • 基于 endValue 是否小于或等于第 no 列的条件值

欢迎任何帮助...

【问题讨论】:

    标签: r dplyr tidyverse purrr


    【解决方案1】:

    一种选择是创建一个list 列,通过replicating 'Y'、'N' 为 'endValue' 列的每个值与 10 的差值,然后 unnest 将其变宽

    library(dplyr)
    library(purrr)
    library(tidyr)
    df %>%
       mutate(new =  map(endValue, ~ rep(c("Y", "N"), c(.x, 10 - .x)))) %>% 
       unnest_wider(new) %>%
       rename_at(vars(starts_with('..')), ~ LETTERS[1:10])
    

    -输出

    # A tibble: 3 x 13
    #     ID name  endValue A     B     C     D     E     F     G     H     I     J    
    #  <int> <chr>    <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
    #1     1 Bob          3 Y     Y     Y     N     N     N     N     N     N     N    
    #2     2 Jim          7 Y     Y     Y     Y     Y     Y     Y     N     N     N    
    #3     3 Fred         4 Y     Y     Y     Y     N     N     N     N     N     N    
    

    或使用separate

    library(stringr)
    df %>%
      mutate(new = str_c(strrep('Y', endValue),
             strrep('N', 10 - endValue))) %>% 
      separate(new, into = LETTERS[1:10], sep="(?<=[A-Z])(?=[A-Z])")
    

    【讨论】:

    • 谢谢@akrun
    【解决方案2】:

    还使用tidyverse 家庭和pmappivot_wider

    library(dplyr)
    library(purrr)
    library(tidyr)
    
    df %>%
      # map each row to a defined function using pmap
      # this function create a long table with 10 rows per ID, name, endValue
      pmap(.f = function(...) { 
        x <- tibble(...)
        y <- tibble(
          ID = x$ID, name = x$name,
          endValue = x$endValue,
          LETTER = LETTERS[1:10],
          value = c(rep("Y", x$endValue), rep("N", 10 - x$endValue)))
      }) %>%
      # combine all the df together
      bind_rows() %>%
      # then pivot_wider to get final result
      pivot_wider(names_from = LETTER, values_from = value)
    #> # A tibble: 3 x 13
    #>      ID name  endValue A     B     C     D     E     F     G     H     I    
    #>   <int> <chr>    <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
    #> 1     1 Bob          3 Y     Y     Y     N     N     N     N     N     N    
    #> 2     2 Jim          7 Y     Y     Y     Y     Y     Y     Y     N     N    
    #> 3     3 Fred         4 Y     Y     Y     Y     N     N     N     N     N    
    #> # … with 1 more variable: J <chr>
    

    reprex package (v2.0.0) 于 2021-04-27 创建

    【讨论】:

    • 谢谢@Sinh
    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多