如何在R语言数据框中提取指定键值对至独立列
问题1:如何在R语言的数据框中从列提取键值对?
可以借助dplyr、stringr和tidyr包处理这类非结构化键值文本,核心思路是拆分文本、识别键值、转换为结构化格式:
代码实现
首先加载用户提供的数据:
# 加载数据 asummy <- structure(list(`arrange_df[, 12]` = c("Customer Name: JOE\nReason for the Call: BP Set Up\nResolution: \nvisual audit on the account\nset expectations in BP\noffered call back\nCenter Location: Clark\nCTN (Number Calling About): ************************************\nAVAYA (Number Calling From): ************************************\nAgent UID: cm***************************u\n", "Name: Kim Putok\nCtn: ************************************\nReason for calling: lost phone/ ************************************/ follow up on insurance claim/ routed to asurion\nResolution:\nLocation: Clark\nattuid: gb***************************r\n", "Customer Name: Heather \nReason for the Call: got suspended / card issue / supposedly paid / complains she just updated online her card then got susp\nResolution: \nCenter Location: Clark\nCTN: ************************************\nAlt No: ************************************\nCredit Reason: ********* courtesy \nAgent UID: rc***************************w/I-EQR******************G\n", "Customer Name: GLORIA ; CTN: ************************************ Affected CTN: ************************************ Alternate Number: none Reason for the Call: change rate plan Resolution: set exp on changing rate plan Agent UID: gt***************************g", "Customer Name: BRANDY \nReason for the Call: payment\nRecommendations/Troubleshooting Steps:\nResolution: explained card errors\nasked for alt # but no good\noffered to use different card or refill card\nsent qp link\nshe will go to bank to check as per cx\nCenter Location:\nCTN: ************************************\nCredit Reason (If credit was applied to account):\nAgent UID: jq***************************n\n", "Customer Name: ; ;Leahi ; Reason for the Call: ; ; ;billing issue / ******************.****************** dollars only orig. bill / due date shld be *********th / why ****************** now? / ctn change questions ; Resolution: ; ;explained bill / ctn change info provided ; Center Location: ;Clark CTN: ; ;************************************ Alt No: Credit Reason: Agent UID: rc***************************w/I-K*********GMDR", "Customer Name: MICHAEL\nReason for the Call: ACCOUNT BAL INQ\n\nRecommendations/Troubleshooting Steps:\n*Account verified and provided information\n\nResolution: \n*calling about the account status\n*suspended due to BBP\n*adv about BP policy\n*Provided payment options\n\nCenter Location:Clark\nCTN************************************:\nCredit Reason (If credit was applied to account):\nAgent UID:rc*********\n", "Customer Name: Kimberly\nCTN: ************************************\nAffected CTN:************************************\nAlternate Number: none\nReason for the Call: add mhs otc $******************\nResolution: added mhs otc $******************\nAgent UID: gt***************************g\n", "auto pop / suspended line\n-cx speaking spanish\n-transfered call\n", "Customer Name: TERRELL ; Reason for the Call: payment Recommendations/Troubleshooting Steps: Resolution: payment success test and validated CTN: ************************************ Credit Reason (If credit was applied to account): Agent UID: jq***************************n" )), row.names = c(NA, 10L), class = "data.frame")
然后提取所有键值对:
library(dplyr) library(stringr) library(tidyr) asummy %>% mutate(row_id = row_number(), # 保留行号,避免丢失文本对应关系 text = str_replace_all(`arrange_df[, 12]`, "\\s*;\\s*", " "), # 清理冗余分号和空格 split_text = str_split(text, "(?<=:)\\s*|\\n")) %>% # 按换行或冒号后边界拆分文本 unnest(split_text) %>% filter(split_text != "") %>% # 过滤空条目 mutate( key = str_extract(split_text, "^[^:]+(?=:)"), # 提取键名 value = str_trim(str_replace(split_text, "^[^:]+:\\s*", "")), # 提取对应值 key = str_trim(key) ) %>% filter(!is.na(key)) %>% # 过滤无法识别为键值对的内容 pivot_wider(names_from = key, values_from = value, values_fn = ~paste(., collapse = "\n")) %>% select(-text)
该方法会自动识别所有键名: 值格式的内容,处理多行值、空格冗余等问题,最终将每个键转为独立列。
问题2:如何仅提取'Reason for the Call'和'Resolution'拆分为独立列?
针对特定字段,用精准正则匹配兼容字段名变体(如Reason for calling),同时保留多行内容:
代码实现
asummy %>% mutate( # 提取Reason字段,兼容"Reason for the Call"和"Reason for calling"写法 `Reason for the Call` = str_extract(`arrange_df[, 12]`, "(?<=Reason for (the )?call:).*?(?=\\n[^\\s]|$)"), # 提取Resolution字段,捕获到下一个键名或文本结尾的所有内容 Resolution = str_extract(`arrange_df[, 12]`, "(?<=Resolution:).*?(?=\\n[^\\s]|$)"), # 清理多余换行、分号和首尾空格 across(c(`Reason for the Call`, Resolution), ~str_trim(str_replace_all(., "\\s*;\\s*|\\n+", " "))) ) %>% select(`Reason for the Call`, Resolution)
说明
- 正则
(?<=Reason for (the )?call:)用正向断言匹配不同写法的Reason字段名 .*?(?=\\n[^\\s]|$)确保捕获完整的字段值(包括多行内容),直到下一个非空白开头的行(即下一个键名)- 对无目标字段的行,结果显示为
NA,符合预期
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

