【问题标题】:Splitting string values containing columns and simultaneously duplicating other column values in a dataframeR - 拆分包含列的字符串值并同时复制数据框中的其他列值
【发布时间】:2022-01-18 15:14:35
【问题描述】:

我有一个包含 3 列的数据框。第一个具有字符串值,其中一些包含逗号,另外两个:ID 和区域信息。

df <- data.frame(column1 = c("ab 34, 35, 36", "cb 23", "df 45, 46", "gh 21"),
                 column2 = c("ID_27", "ID_28", "ID_29", "ID_30"),
                 column3 = c("area51", "area52", "area53", "area54"))
head(df)
column1 column2 column3
1 ab 34, 35, 36   ID_27  area51
2         cb 23   ID_28  area52
3     df 45, 46   ID_29  area53
4         gh 21   ID_30  area54

我想要做的是修改第一列中的值,以便逗号分隔值消失,将两个字母前缀应用于每个数字值,并在新行中重新排列以逗号分隔的每个值。同时,复制其他列中的值,如下例:

new_df <- data_frame(column1 = c("ab34", "ab35", "ab36", "cb23", "df45", "df46", "gh21"),
                     column2 = c("ID_27", "ID_27", "ID_27", "ID_28", "ID_29", "ID_29", "ID_30"),
                     column3 = c("area51", "area51", "area51", "area52", "area53", "area53", "area54"))
head(new_df)
# A tibble: 6 x 3
column1 column2 column3
<chr>   <chr>   <chr>  
1 ab34    ID_27   area51 
2 ab35    ID_27   area51 
3 ab36    ID_27   area51 
4 cb23    ID_28   area52 
5 df45    ID_29   area53 
6 df46    ID_29   area53 

有人知道什么 R 代码可以实现这一点吗?使用 tidyverse 还是旧方法?顺便说一句,无需从数据框转到 tibble,这仅用于示例。我的目标是转换数据框。

【问题讨论】:

    标签: r string dataframe split comma


    【解决方案1】:

    一个可能的解决方案:

    library(tidyverse)
    
    df <- data.frame(column1 = c("ab 34, 35, 36", "cb 23", "df 45, 46", "gh 21"),
                     column2 = c("ID_27", "ID_28", "ID_29", "ID_30"),
                     column3 = c("area51", "area52", "area53", "area54"))
    
    df %>% 
      mutate(column1 = str_replace_all(column1,", ", str_extract(column1,"^\\S+")) %>%
                       str_remove(.," ")) %>% 
      separate_rows(column1, sep = "(?<=\\d)(?=\\D)")
    
    #> # A tibble: 7 × 3
    #>   column1 column2 column3
    #>   <chr>   <chr>   <chr>  
    #> 1 ab34    ID_27   area51 
    #> 2 ab35    ID_27   area51 
    #> 3 ab36    ID_27   area51 
    #> 4 cb23    ID_28   area52 
    #> 5 df45    ID_29   area53 
    #> 6 df46    ID_29   area53 
    #> 7 gh21    ID_30   area54
    

    【讨论】:

    • 太棒了!非常感谢你们!
    【解决方案2】:

    这是一个(希望)更容易理解的分步方法:

    library(dplyr)
    library(stringr)
    library(tidyr)
    df %>% 
      mutate(
        # extract the prefix:
        prefix = str_extract(column1,"^\\w+"),
        # extract the digits in a list:
        digits = str_extract_all(column1,"\\d+")) %>% 
      # cast the list values in `digits` into long format:
      unnest_longer(digits) %>%
      # paste `prefix`, `digits` together:
      mutate(column1 = paste0(prefix, digits)) %>%
      # remove obsolete columns:
      select(-c(prefix, digits))
    # A tibble: 7 × 3
      column1 column2 column3
      <chr>   <chr>   <chr>  
    1 ab34    ID_27   area51 
    2 ab35    ID_27   area51 
    3 ab36    ID_27   area51 
    4 cb23    ID_28   area52 
    5 df45    ID_29   area53 
    6 df46    ID_29   area53 
    7 gh21    ID_30   area54 
    

    【讨论】:

      猜你喜欢
      • 2021-07-26
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 2021-10-21
      • 1970-01-01
      • 2020-08-07
      相关资源
      最近更新 更多