在R dplyr中,计算一个数据框中的字符串出现在另一个数据框中的次数。

7

我有两个数据框,它们看起来像这样:

df1 <- data.frame(reference=c("cat","dog"))
print(df1)
#>   reference
#> 1       cat
#> 2       dog
df2 <- data.frame(data=c("cat","car","catt","cart","dog","dog","pitbull"))
print(df2)
#>      data
#> 1     cat
#> 2     car
#> 3    catt
#> 4    cart
#> 5     dog
#> 6     dog
#> 7 pitbull

2021-12-29 由 reprex package (v2.0.1) 创建

我想找出 df1 中单词 cat 和 dog 在 df2 中出现的次数。 我希望我的数据看起来像这样

animals   n
cat       1
dog       2

非常感谢您的帮助和指导。我的参考列表很长,我尝试使用grep命令查找每一个,但这需要花费我很多时间。

感谢您抽出宝贵的时间阅读此邮件。祝您节日快乐!


1
回复:“我尝试了对每个进行grep” - 当你在进行模式匹配或部分字符串匹配时,你需要使用grep和正则表达式。当你像这里一样匹配整个精确字符串时,你只需要使用==%in%或其他非正则表达式函数(正如所有答案所示)。 - Gregor Thomas
6个回答

6

更新:感谢Gregor Thomas。

library(dplyr)

left_join(df1,df2, by=c("reference"="data")) %>% 
  count(reference)

输出:

  reference n
1       cat 1
2       dog 2

我们可以使用 `semi_join` 然后再使用 `count`:
library(dplyr)

semi_join(df2,df1, by=c("data"="reference")) %>% 
  count(data)

  data n
1  cat 1
2  dog 2

2
我会坚持使用 left_join(df1, df2),除非 OP 明确指定他们想要省略具有 0 计数的 reference 行。 - Gregor Thomas
感谢Gregor Thomas。我会更新的。 - TarJae

4

使用联接可能会更快。

library(data.table)
setDT(df2)[, .(animals = data)][df1, .(n = .N), 
     on = .(animals = reference), by = .EACHI]
   animals n
1:     cat 1
2:     dog 2

或者在 base R 中对数据进行 subset 后使用 table

table(subset(df2, data %in% df1$reference, select = data))

4
一种可能的解决方案是基于tidyverse的:
library(tidyverse)

df1 <- data.frame(reference=c("cat","dog"))
df2 <- data.frame(data=c("cat","car","catt","cart","dog","dog","pitbull"))

df1 %>% 
  group_by(animal = reference) %>% 
  summarise(n = sum(reference == df2$data), .groups = "drop")

#> # A tibble: 2 × 2
#>   animal     n
#>   <chr>  <int>
#> 1 cat        1
#> 2 dog        2

2
我们可以使用str_count函数,将第二个数据框中的列合并为一个字符串后进行计数。
library(tidyverse)

df1 %>%
  transmute(animals = reference, n = str_c(df2$data, collapse = " ") %>%
    str_count(str_c("\\b", reference, "\\b")) )
#>   animals n
#> 1     cat 1
#> 2     dog 2

reprex包(v2.0.1)于2021年12月29日创建


2
这里有第三个选项:
library(tidyverse)

df1 <- tibble(reference=c("cat","dog"))
df2 <- tibble(data=c("cat","car","catt","cart","dog","dog","pitbull"))

df2 |>
  count(data) |>
  filter(data %in% df1$reference) |>
  rename(animal = data)
#> # A tibble: 2 x 2
#>   animal     n
#>   <chr>  <int>
#> 1 cat        1
#> 2 dog        2

1
df1$n <- colSums(outer(df2$data, df1$reference, '=='))

df1
#>   reference n
#> 1       cat 1
#> 2       dog 2

哇,非常棒的作品。谢谢,印象深刻。 - LDT

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