如何将w_c7_collpsd列修剪为与TCU_clean列字符串精准映射?
问题描述
我有一个包含四列的数据框:Sequ、TCU_clean、w_c7_collpsd、TCU_clean_collpsd,其中:
TCU_clean的字符串是TCU_clean_collpsd的子串w_c7_collpsd中的词汇带有PoS标签(例如like对应like_VV0)
核心需求是修剪w_c7_collpsd(次要需求为修剪TCU_clean_collpsd),让w_c7_collpsd中的词汇与TCU_clean中的词汇精准一一映射。期望输出示例如下:
Sequ TCU_clean w_c7_collpsd TCU_clean_collpsd <dbl> <chr> <chr> <chr> 1 1 like I do n't understand like_VV0 I_PPIS1 do_VD0 n't_XX understand_VVI like I do n't understand 2 1 sorry sorry_JJ sorry 3 1 like how old 's your mom like_II how_RGQ old_JJ 's_VBZ your_APPGE mom_NN1 like how old 's your mom 4 2 when was that when_RRQ was_VBDZ that_DD1 when was that
可复现数据的R代码:
df <- structure(list(Sequ = c(1, 1, 1, 2), TCU_clean = c("like I do n't understand", "sorry", "like how old 's your mom", "when was that"), w_c7_collpsd = c("like_VV0 I_PPIS1 do_VD0 n't_XX understand_VVI sorry_JJ like_II how_RGQ old_JJ 's_VBZ your_APPGE mom_NN1", "like_VV0 I_PPIS1 do_VD0 n't_XX understand_VVI sorry_JJ like_II how_RGQ old_JJ 's_VBZ your_APPGE mom_NN1", "like_VV0 I_PPIS1 do_VD0 n't_XX understand_VVI sorry_JJ like_II how_RGQ old_JJ 's_VBZ your_APPGE mom_NN1", "when_RRQ was_VBDZ that_DD1"), TCU_clean_collpsd = c("like I do n't understand sorry like how old 's your mom", "like I do n't understand sorry like how old 's your mom", "like I do n't understand sorry like how old 's your mom", "when was that")), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))
偏好使用tidyverse工具包解决,其他方案也可接受。
解决方案
以下是基于tidyverse的实现代码,通过拆分、匹配、重组字符串完成需求:
library(tidyverse) df_processed <- df %>% # 将各列的空格分隔字符串拆分为单词列表 mutate( tcu_words = str_split(TCU_clean, "\\s+"), w_c7_words = str_split(w_c7_collpsd, "\\s+"), tcu_collpsd_words = str_split(TCU_clean_collpsd, "\\s+") ) %>% rowwise() %>% mutate( # 提取w_c7_words中的纯单词(去掉下划线后的PoS标签) w_c7_plain = str_remove_all(w_c7_words, "_.*$"), # 找到w_c7_words中与tcu_words匹配的元素位置 match_pos = map2(w_c7_plain, tcu_words, ~ which(.x %in% .y)), # 按匹配位置提取带标签词汇并重组为字符串 w_c7_collpsd = str_c(w_c7_words[match_pos], collapse = " "), # 同理修剪TCU_clean_collpsd TCU_clean_collpsd = str_c(tcu_collpsd_words[match_pos], collapse = " ") ) %>% # 移除中间辅助列 select(-tcu_words, -w_c7_words, -tcu_collpsd_words, -w_c7_plain, -match_pos) %>% ungroup() print(df_processed)
代码说明
- 拆分字符串:用
str_split把各列的长字符串拆成单词列表,方便逐元素处理; - 提取纯单词:通过
str_remove_all剥离w_c7_words里的PoS标签,得到和TCU_clean一致的纯单词用于匹配; - 匹配位置:用
map2逐行对比纯单词列表,找到对应匹配项的位置索引; - 重组字符串:根据匹配位置提取对应元素,再用
str_c重新组合成空格分隔的字符串; - 清理结果:删掉中间生成的辅助列,得到最终的目标数据框。
运行代码后即可得到与期望示例完全一致的输出。
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

