【问题标题】:Count how many times strings from one data frame appear to another data frame in R dplyr计算一个数据帧中的字符串出现在 R dplyr 中的另一个数据帧的次数
【发布时间】:2021-12-29 20:11:15
【问题描述】:

我有两个如下所示的数据框:

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

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

我想知道 df1 中的 cat 和 dog 单词在 df2 中存在多少次。 我希望我的数据看起来像这样

animals   n
cat       1
dog       2

感谢任何帮助或指导。我的参考清单很大。我试图对它们中的每一个进行 grep,但会花时间。

感谢您的宝贵时间。节日快乐

【问题讨论】:

  • 回复:“我试图对每一个都进行 grep” - 当您进行模式匹配或部分字符串匹配时,您需要 grep 和 regex。当您在这里匹配整个精确字符串时,您只需要 ==%in% 或其他非正则表达式函数(如这里的所有答案所示)。

标签: r dplyr tidyverse stringr


【解决方案1】:

更新:感谢 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

【讨论】:

  • 我会坚持使用left_join(df1, df2),除非 OP 明确指定他们要省略计数为 0 的 reference 行。
  • 感谢格雷戈尔·托马斯。会更新。
【解决方案2】:

一个可能的解决方案,tidyverse-based:

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

【讨论】:

    【解决方案3】:

    加入可能会更快

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

    或者在subsetingbase R中的数据之后使用table

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

    【讨论】:

      【解决方案4】:

      这是第三种选择:

      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
      

      【讨论】:

        【解决方案5】:

        我们可以使用str_count,将第二个df中的列折叠成一个字符串。

        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 package (v2.0.1) 于 2021 年 12 月 29 日创建

        【讨论】:

          【解决方案6】:
          df1$n <- colSums(outer(df2$data, df1$reference, '=='))
          
          df1
          #>   reference n
          #> 1       cat 1
          #> 2       dog 2
          

          【讨论】:

          • 哇一个非常不错的。谢谢,令人印象深刻
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-07
          • 1970-01-01
          • 1970-01-01
          • 2014-06-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多