根据R中的分隔符将单列转换为多列

Convert a single column into multiple columns based on delimiter in R

我有以下数据框:

ID Parts
-- -----
1  A:B::
2  X2:::
3  ::J4:
4  A:C:D:G4:X6

我想通过 : 分隔符将 Parts 列转换为多个列。所以它应该看起来像:

ID A  B  X2  J4  C  D  G4  X6 ........
-- -  -  --  --  -  -  --  -- 
1  A  B  na  na  na na na  na
2  na na X2  na  na na na  na
3  na na na  J4  na na na  na
4  A  na na  na  C  D  G4  X6

在那里我不会提前知道潜在的列数。

我在这方面遇到了我的对手 - delim 的 strsplit() 我可以做到,但只能在 Parts

中使用固定数量的实体

tidyr 中的 seperate 函数是您要找的吗?

https://tidyr.tidyverse.org/reference/separate.html

它可能需要一些花哨的正则表达式实现,但可能会起作用。

您可以组合使用 tidyr::seperatetidyr::pivot_widertidyr::pivot_longer。首先你仍然可以使用strsplit来确定列的数量Parts拆分为而不是唯一值的数量(工作原理):

library(dplyr)
library(tidyr)
library(stringr)

n_col <- max(stringr::str_count(df$Parts, ":")) + 1

df %>% 
  tidyr::separate(Parts, into = paste0("col", 1:n_col), sep = ":") %>% 
  dplyr::mutate(across(everything(), ~dplyr::na_if(., ""))) %>% 
  tidyr::pivot_longer(-ID) %>% 
  dplyr::select(-name) %>% 
  tidyr::drop_na() %>% 
  tidyr::pivot_wider(id_cols = ID,
                     names_from = value)


     ID A     B     X2    J4    C     D     G4    X6   
  <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1     1 A     B     NA    NA    NA    NA    NA    NA   
2     2 NA    NA    X2    NA    NA    NA    NA    NA   
3     3 NA    NA    NA    J4    NA    NA    NA    NA   
4     4 A     NA    NA    NA    C     D     G4    X6 

工作原理

使用此代码您不需要知道唯一值的数量——枢轴会处理这个问题。您需要知道的是 Parts 将被拆分成多少个新列 seperate。这很容易做到,只需计算定界符的数量并用 str_count 添加一个即可。这样你就有了合适的列数来用你的分隔符将 Parts 分隔成。

这是因为 pivot_longer 将创建一个包含重复 ID 的两列数据框和一个包含分隔值 Parts 的列——一个 IDParts配对。然后,当您使用 pivot_wider 时,会为 Parts 的每个唯一值自动创建列,并且该值保留在列中。此函数会在未找到 IDParts 组合的情况下自动填充 NA

逐条尝试 运行 以便在需要时更好地理解。


数据

lines <- "
ID Parts
1  A:B::
2  X2:::
3  ::J4:
4  A:C:D:G4:X6
"

df <- read.table(text = lines, header = T)