这是您的数据:
df <- data.frame(ID = 1:5,
X = c("1 sandwich 2 hamburger",
"1 sandwich 4 salad 5 soda 7 soup",
"0 chicken wings",
NA,
NA))
注意:如果您使用 R>4.0,则无需指定 stringsAsFactors = FALSE,因为它是新的默认值。
脏但有效
library(dplyr) # only with version > 1.0
library(stringr)
df %>%
summarise(ID = ID,
as.data.frame(do.call(rbind, str_extract_all(X, "[[:digit:]+]") %>%
lapply(`length<-`, max(lengths(.))))))
#> ID V1 V2 V3 V4
#> 1 1 1 2 <NA> <NA>
#> 2 2 1 4 5 7
#> 3 3 0 <NA> <NA> <NA>
#> 4 4 <NA> <NA> <NA> <NA>
#> 5 5 <NA> <NA> <NA> <NA>
额外的想法
我想指出,如果需要,您仍然可以保留有关文本的信息。 [这只是为了帮助你提供一些新的想法]
library(tidyr)
library(dplyr)
tmp <- df %>%
separate_rows(X, sep = "(?<=.)(?=[[:digit:]+])") %>%
separate(X, c("n", "txt"), sep = " ", extra = "merge")
tmp
#> # A tibble: 9 x 3
#> ID n txt
#> <int> <chr> <chr>
#> 1 1 1 "sandwich "
#> 2 1 2 "hamburger"
#> 3 2 1 "sandwich "
#> 4 2 4 "salad "
#> 5 2 5 "soda "
#> 6 2 7 "soup"
#> 7 3 0 "chicken wings"
#> 8 4 <NA> <NA>
#> 9 5 <NA> <NA>
鉴于此,您可以使用以下代码获得所需的结果:
tmp %>%
group_by(ID) %>%
mutate(x = row_number()) %>%
ungroup() %>%
select(-txt) %>%
pivot_wider(names_from = x, values_from = n, names_prefix = "X")
#> # A tibble: 5 x 5
#> ID X1 X2 X3 X4
#> <int> <chr> <chr> <chr> <chr>
#> 1 1 1 2 <NA> <NA>
#> 2 2 1 4 5 7
#> 3 3 0 <NA> <NA> <NA>
#> 4 4 <NA> <NA> <NA> <NA>
#> 5 5 <NA> <NA> <NA> <NA>