将文本字符串解析成多个列并提取数据值。

5
我有一个如下所示的大型数据集:
ID 成绩
1 英语 3,法语 7,地理 8
2 西班牙语 7,古典文学 4
3 物理 5,英语 5,体育 7,艺术 4
我需要将成绩列中的文本字符串解析为每个学科的单独列,并将每个人的分数存储为数据值,如下所示:
ID 英语 法语 地理 西班牙语 古典文学 物理 体育 艺术
1 3 7 8 - - - - -
2 - - - 7 4 - - -
3 5 - - - - 5 7 4
由于完整数据集中有数百个表格,我无法手动预定义列。到目前为止,我已经清理了数据,以消除不一致的大小写,并将每个学科-成绩配对分开到一个独立的列中。
df$scores2 <- str_to_lower(df$Scores)
split <- separate(
  df,
  scores2,
  into = paste0("Subject", 1:8),
  sep = "\\,",
  remove = FALSE,
  convert = FALSE,
  extra = "warn",
  fill = "warn",
)

我查看了多个与该主题相关的问题,例如 在 R 中将不规则文本列拆分为多个列,但我找不到另一个类似于列标题和数据值混合在文本字符串中的情况。我应该如何生成所需的全部列并填充数据值?

2个回答

3
您可以先使用strsplit函数将Scores列拆分为科目-分数对(这将是一个列表),然后将列表列unnest为行。接下来,将科目-分数对separateSubjectScore列。最后将数据从“长格式”转换为“宽格式”。
感谢@G. Grothendieck改进我的代码:)
library(tidyverse)

df %>% 
  separate_rows(Scores, sep = ", ") %>% 
  separate(Scores, sep = " ", into = c("Subject", "Score")) %>% 
  pivot_wider(names_from = "Subject", values_from = "Score")

# A tibble: 3 × 9
     ID English French Geography Spanish Classics Physics PE    Art  
  <int> <chr>   <chr>  <chr>     <chr>   <chr>    <chr>   <chr> <chr>
1     1 3       7      8         NA      NA       NA      NA    NA   
2     2 NA      NA     NA        7       4        NA      NA    NA   
3     3 5       NA     NA        NA      NA       5       7     4    

1
mutateunnest行可以替换为separate_rows(Scores, sep = ", ") %>%。此外,可以省略everything()参数。 - G. Grothendieck

0

使用 data.table

library(data.table)

setDT(dt)

dt <- dt[, .(class_grade = unlist(str_split(Scores, ", "))), by = ID]
dt[, c("class", "grade") := tstrsplit(class_grade, " ")]
dcast(dt, ID ~ class, value.var = c("grade"), sep = "")

结果

#    ID  Art Classics English French Geography   PE Physics Spanish
# 1:  1 <NA>     <NA>       3      7         8 <NA>    <NA>    <NA>
# 2:  2 <NA>        4    <NA>   <NA>      <NA> <NA>    <NA>       7
# 3:  3    4     <NA>       5   <NA>      <NA>    7       5    <NA>

数据

dt <- structure(list(ID = 1:3, Scores = c("English 3, French 7, Geography 8", 
"Spanish 7, Classics 4", "Physics 5, English 5, PE 7, Art 4")), row.names = c(NA, 
-3L), class = c("data.frame"))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接