除了 Ronak 的回答,我留下代码来处理您的其他问题。在这里,我创建了一个数据集,该数据集比您的数据集要复杂一些,以考虑额外的问题。与 Ronak 类似,我创建了两个列。不同之处在于我为每一行创建了一个字符串,包括所有汽车。例如,参见temp 中的第二行。
对于额外的问题,我创建了另一个数据框。 left 和 right 中可能有多辆汽车。我梳理了left 和right 中的字符串,并展开了数据框。这是out。然后,我总结了左右车的频率,并合并了两个数据集。
library(tidyverse)
library(stringi)
group_by(mydf, person) %>%
mutate(left = stri_extract_all_regex(str = text,
pattern = "(?<=on the left )car[0-9]+?") %>%
unlist %>% toString,
right = stri_extract_all_regex(str = text,
pattern = "(?<=on the right )car[0-9]+?") %>%
unlist %>% toString) %>%
ungroup-> temp
temp
person text left right
<chr> <chr> <chr> <chr>
1 Max Ana is on the left car2. Bob is on the right car4. They are not far away from each other. car2 car4
2 John I saw a garage on the right car1. There is a garage on the right car3. NA car1, car3
3 Ana There is a garage on the right car3. There is another garage on the right car3. NA car3, car3
dplyr::select(temp, person, left, right) %>%
Reduce(f = separate_rows_, x = c("left", "right")) -> out
count(out, person, left, name = "left_total") %>%
full_join(count(out, person, right, name = "right_total"))
person left left_total right right_total
<chr> <chr> <int> <chr> <int>
1 Ana NA 2 car3 2
2 John NA 2 car1 1
3 John NA 2 car3 1
4 Max car2 1 car4 1
另一种解决方案
另一种方法是将 quanteda 包与 tidyverse 包一起使用。这更容易找到词频。您仍然需要修改docname。但这很容易做到。
library(quanteda)
kwic(mydf$text, pattern = "car[0-9]+?",
window = 1, valuetype = "regex") %>%
as.data.frame %>%
dplyr::select(docname, pre, keyword) %>%
count(docname, keyword, pre, name = "frequency")
docname keyword pre frequency
<chr> <chr> <chr> <int>
1 text1 car2 left 1
2 text1 car4 right 1
3 text2 car1 right 1
4 text2 car3 right 1
5 text3 car3 right 2
数据
person text
1 Max Ana is on the left car2. Bob is on the right car4. They are not far away from each other.
2 John I saw a garage on the right car1. There is a garage on the right car3.
3 Ana There is a garage on the right car3. There is another garage on the right car3.