在R中将一列(不同格式)分隔为多列

owfi6suc  于 2023-03-27  发布在  其他
关注(0)|答案(2)|浏览(228)

我在R中有一个91列51000行的数据框:第一列是我发现的每种生物的分类学分类(“分类”),剩下的是每个样本中的丰度(“S1”,“S2”,“S3”,直到“S90”)。我想将第一列分成六个:列'K'、'P'、'C'、'O'、'F'和'G'。问题是有些单元格的数据不完整,如果我用分号分隔单元格,这些单元格生成的列数会比预期的少。
当前 Dataframe :
| 分类|
| --------------|
| k__细菌|
| k__细菌;g__链梭菌|
| k__细菌;慢球菌属|
| k__细菌;p__慢球菌属;c__寡球菌;〇__寡聚物;f__〇 l|
| k__细菌;p__慢球菌属;c__寡球菌;o__寡聚物;f__Ol;g__Ol|
我的问题是:我可以根据后缀来分隔和组织我的单元格吗?我希望有一个列'K',其中包含所有以'k__'开头的信息,一个列'P',其中包含所有以'p__'开头的信息,等等。空单元格可以用NA填充。
理想的 Dataframe :
| K|P|C|O|F|G|
| --------------|--------------|--------------|--------------|--------------|--------------|
| k__细菌|不适用|不适用|不适用|不适用|不适用|
| k__细菌|不适用|不适用|不适用|不适用|g__链梭菌|
| k__细菌|慢球菌属|不适用|不适用|不适用|不适用|
| k__细菌|慢球菌属|c__寡球菌|o__寡聚体|f__0l|不适用|
| k__细菌|慢球菌属|c__寡球菌|o__寡聚体|f__0l|g__Ol|
拜托,谁能帮帮我?
我试着使用tidyr包中的“separate”函数。

ar7v8xwq

ar7v8xwq1#

一种选择是使用tidyr::separate_longer_delim(需要tidyr 1.3.0)和pivot_wider,如下所示:

library(tidyr)
library(dplyr)

dat |>
  mutate(row = row_number()) |> 
  separate_longer_delim(Classification, delim = ";") |> 
  mutate(suffix = toupper(substr(Classification, 1, 1))) |> 
  pivot_wider(names_from = suffix, values_from = Classification) |> 
  select(-row)
#> # A tibble: 5 × 6
#>   K           G               P                C               O          F    
#>   <chr>       <chr>           <chr>            <chr>           <chr>      <chr>
#> 1 k__Bacteria <NA>            <NA>             <NA>            <NA>       <NA> 
#> 2 k__Bacteria g__Streptofusia <NA>             <NA>            <NA>       <NA> 
#> 3 k__Bacteria <NA>            p__Lentisphaerae <NA>            <NA>       <NA> 
#> 4 k__Bacteria <NA>            p__Lentisphaerae c__Oligosphaeri o__Oligosp f__Ol
#> 5 k__Bacteria g__Ol           p__Lentisphaerae c__Oligosphaeri o__Oligosp f__Ol

数据

dat <- data.frame(
  Classification = c(
    "k__Bacteria",
    "k__Bacteria;g__Streptofusia", "k__Bacteria;p__Lentisphaerae",
    "k__Bacteria;p__Lentisphaerae;c__Oligosphaeri;o__Oligosp;f__Ol",
    "k__Bacteria;p__Lentisphaerae;c__Oligosphaeri;o__Oligosp;f__Ol;g__Ol"
  )
)
oyxsuwqo

oyxsuwqo2#

尝试separate_wider_regex,它非常适合这个用例。魔术发生在参数“patterns”上,它是一个可选命名元素的向量。未命名的元素被丢弃(在本例中是分号),但命名的元素被提取到带有名称的列中。

library(tidyr) #version 1.3.0

separate_wider_regex( data = dat,
                      col = Classification,
                      patterns = c(K = "k_+\\w+",
                                   ";",
                                   P = "p_+\\w+",
                                   ";",
                                   C = "c_+\\w+",
                                   ";",
                                   O = "o_+\\w+",
                                   ";",
                                   F = "f_+\\w+",
                                   ";",
                                   G = "g_+\\w+"
                                   ),
                      too_few = "align_start"
                      )

# A tibble: 5 × 6
  K           P                C               O       F     G    
  <chr>       <chr>            <chr>           <chr>   <chr> <chr>
1 k__Bacteria NA               NA              NA      NA    NA   
2 k__Bacteria NA               NA              NA      NA    NA   
3 k__Bacteria p__Lentisphaerae NA              NA      NA    NA   
4 k__Bacteria p__Lentisphaerae c__Oligosphaeri o__Oli… f__Ol NA   
5 k__Bacteria p__Lentisphaerae c__Oligosphaeri o__Oli… f__Ol g__Ol
  • OBS:正如@stefan所指出的,这并不完全正确,因为当模式的顺序改变时,输出会丢失一些值。绝对值得展示separate_wider_regex thoguh,所以我在尝试修复它时会保留这个答案。

相关问题