R将列中的特定文本提取到多列中

R Extract specific text from column into multiple columns

我有一个以这种格式从网络导出的数据框

id vals
1  {7,12,58,1}
2  {1,2,5,7}  
3  {15,12} 

我想像这样只将数字(忽略卷曲和逗号)提取到多个列中

id val_1 val_2 val_3 val_4 val_5
1  7     12    58    1
2  1     2     5     7  
3  15    12  

尽管我们得到的最大值是 4,但我希望始终达到值 val_5。

谢谢!

我们可以为此使用 str_extract_all

library(dplyr)
library(stringr)

df %>% 
  mutate(vals = str_extract_all(vals, '\d+', ''))

或@akrun 在评论中建议

df %>% 
  mutate(vals = str_extract_all(vals, '\d+', '')) %>% 
  do.call(data.frame, .)
  id vals.1 vals.2 vals.3 vals.4
1  1      7     12     58      1
2  2      1      2      5      7
3  3     15     12   <NA>   <NA>

数据:

df <- structure(list(id = 1:3, vals = c("{7,12,58,1}", "{1,2,5,7}", 
"{15,12}")), class = "data.frame", row.names = c(NA, -3L))

另一个可能的 tidyverse 选项,我们删除大括号,然后分隔 , 上的行,然后转向宽格式。然后,我们可以根据列名中的最大值(在本例中为 4)创建附加列(使用 tibble 中的 add_column),然后可以创建 val_5

library(tidyverse)

df %>%
  mutate(vals = str_replace_all(vals, "\{|\}", "")) %>%
  separate_rows(vals, sep=",") %>%
  group_by(id) %>%
  mutate(ind = row_number()) %>%
  pivot_wider(names_from = ind, values_from = vals, names_prefix = "val_") %>%
  add_column(!!(paste0("val_", parse_number(names(.)[ncol(.)])+1)) := NA)

输出

  id val_1 val_2 val_3 val_4 val_5
1  1     7    12    58     1    NA
2  2     1     2     5     7    NA
3  3    15    12  <NA>  <NA>    NA

数据

df <- read.table(text = "id vals
1  {7,12,58,1}
2  {1,2,5,7}
3  {15,12} ", header = T)

使用data.table

library(data.table)
library(stringi)
result <- setDT(df)[, stri_match_all_regex(vals, '\d+')[[1]], by=.(id)]
result[, item:=paste('val', 1:.N, sep='_'), by=.(id)]   # defines column names
dcast(result, id~item, value.var = 'V1')                # convert from long to wide
##    id val_1 val_2 val_3 val_4
## 1:  1     7    12    58     1
## 2:  2     1     2     5     7
## 3:  3    15    12  <NA>  <NA>