我有两个任意的人 A 和 B 之间的对话记录。
c1 <- "Person A: blabla...something Person B: blabla something else Person A: OK blabla"
c2 <- "Person A: again blabla Person B: blabla something else Person A: thanks blabla"
数据框如下所示:
df <- data.frame(id = rbind(123, 345), conversation = rbind(c1, c2))
df
id conversation
c1 123 Person A: blabla...something Person B: blabla something else Person A: OK blabla
c2 345 Person A: again blabla Person B: blabla something else Person A: thanks blabla
现在我只想提取人 A 的部分并将其放入数据框中。结果应该是:
id person_A
1 123 blabla...something OK blabla
2 345 again blabla thanks blabla
最佳答案
我非常喜欢以一种让您访问所有数据(也包括人员 B 的话语)的方式解决此类问题。我爱 整理 的 extract
对于这种列拆分。我以前用过 do.call(rbind, strsplit()))
接近但爱多么干净extract
方法是。
c1 <- "Person A: blabla...something Person B: blabla something else Person A: OK blabla"
c2 <- "Person A: again blabla Person B: blabla something else Person A: thanks blabla"
c3 <- "Person A: again blabla Person B: blabla something else"
df <- data.frame(id = rbind(123, 345, 567), conversation = rbind(c1, c2, c3))
if (!require("pacman")) install.packages("pacman")
pacman::p_load(dplyr, tidyr)
conv <- strsplit(as.character(df[["conversation"]]), "\\s+(?=Person\\s)", perl=TRUE)
df2 <- df[rep(1:nrow(df), sapply(conv, length)), ,drop=FALSE]
rownames(df2) <- NULL
df2[["conversation"]] <- unlist(conv)
df2 %>%
extract(conversation, c("Person", "Conversation"), "([^:]+):\\s+(.+)")
## id Person Conversation
## 1 123 Person A blabla...something
## 2 123 Person B blabla something else
## 3 123 Person A OK blabla
## 4 345 Person A again blabla
## 5 345 Person B blabla something else
## 6 345 Person A thanks blabla
## 7 567 Person A again blabla
## 8 567 Person B blabla something else
df2 %>%
extract(conversation, c("Person", "Conversation"), "([^:]+):\\s+(.+)") %>%
filter(Person == "Person A")
## id Person Conversation
## 1 123 Person A blabla...something
## 2 123 Person A OK blabla
## 3 345 Person A again blabla
## 4 345 Person A thanks blabla
## 5 567 Person A again blabla
或者在所需的输出中显示时折叠它们:
df2 %>%
extract(conversation, c("Person", "Conversation"), "([^:]+):\\s+(.+)") %>%
filter(Person == "Person A") %>%
group_by(id) %>%
select(-Person) %>%
summarise(Person_A =paste(Conversation, collapse=" "))
## id Person_A
## 1 123 blabla...something OK blabla
## 2 345 again blabla thanks blabla
## 3 567 again blabla
编辑 :实际上,我怀疑您的数据具有真实姓名,例如“约翰·史密斯”与“A 人”。如果是这种情况,此初始正则表达式拆分将捕获使用大写字母后跟冒号的名字和姓氏:
c1 <- "Greg Smith: blabla...something Sue Williams: blabla something else Greg Smith: OK blabla"
c2 <- "Greg Smith: again blabla Sue Williams: blabla something else Greg Smith: thanks blabla"
c3 <- "Greg Smith: again blabla Sue Williams: blabla something else"
df <- data.frame(id = rbind(123, 345, 567), conversation = rbind(c1, c2, c3))r
conv <- strsplit(as.character(df[["conversation"]]), "\\s+(?=([A-Z][a-z]+\\s+[A-Z][a-z]+:))", perl=TRUE)
df2 <- df[rep(1:nrow(df), sapply(conv, length)), ,drop=FALSE]
rownames(df2) <- NULL
df2[["conversation"]] <- unlist(conv)
df2 %>%
extract(conversation, c("Person", "Conversation"), "([^:]+):\\s+(.+)")
## id Person Conversation
## 1 123 Greg Smith blabla...something
## 2 123 Sue Williams blabla something else
## 3 123 Greg Smith OK blabla
## 4 345 Greg Smith again blabla
## 5 345 Sue Williams blabla something else
## 6 345 Greg Smith thanks blabla
## 7 567 Greg Smith again blabla
## 8 567 Sue Williams blabla something else
关于regex - 如何在两个人 A 和 B 之间的对话中仅提取人 A 的陈述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29817928/