代码之家  ›  专栏  ›  技术社区  ›  geoscience123

如何计算R中一个表列与另一个数据帧的匹配数?

  •  3
  • geoscience123  · 技术社区  · 6 天前

    我有两组数据:

    第一个数据帧( small )相对小于第二数据帧( large ). 每个数据帧都有一个 id 具有唯一标识符的列。较小的数据帧有一个名为 links ,其中包含到较大的第二数据帧的链接列表。较大的数据帧有一列属性,我们将调用 att :

    library(tidyverse)
    
    a <- c(3, 3, NA, 5)
    b <- c(NA, 3, 4, 5)
    
    small <- tibble(id = c(1, 2),
                    links = list(a, b))
    
    large <- tibble(id = c(3, 4, 5),
                    att = c("yes", "no", "maybe"))
    

    我的目标是统计每次观察的次数 小的 数据帧与观测值有联系 "yes" 属性在 大的 数据帧。

    我觉得这样的事情是在正确的轨道上,但它并不完全正确:

    counted <- small %>%
      mutate(count_yes = map_int(links, ~ sum(large$att[large$id %in% .x] == "yes")))
    
    print(counted)
    #> # A tibble: 2 × 3
    #>      id links     count_yes
    #>   <dbl> <list>        <int>
    #> 1     1 <dbl [4]>         1
    #> 2     2 <dbl [4]>         1
    

    在这里, count_yes 当它应该读作2和1时,它只显示为1。

    2 回复  |  直到 6 天前
        1
  •  3
  •   Ronak Shah    6 天前

    你走在正确的道路上,但需要一些调整。

    small %>%
      mutate(count_yes = map_int(links, ~sum(.x %in% large$id[large$att %in% "yes"])))
    
    #     id links     count_yes
    #  <dbl> <list>        <int>
    #1     1 <dbl [4]>         2
    #2     2 <dbl [4]>         1
    

    或者在基数R中:

    sapply(small$links, \(x) sum(x %in% large$id[large$att %in% "yes"]))
    

    注意使用 %in% 而不是 == 会回来的 FALSE 对于 NA 价值观。

        2
  •  1
  •   SamR    6 天前

    当你在寻找一个 解决方案,我认为这里的一种表达方式是 tidyr::unnest() 那么,这里的列表列 left_join() large summarise() :

    small |>
        tidyr::unnest(links) |>
        left_join(large, by = c("links" = "id")) |>
        summarise(
            links = list(links),
            count_yes = sum(att == "yes", na.rm = TRUE), .by = id
        )
    
    # # A tibble: 2 × 3
    #      id links     count_yes
    #   <dbl> <list>        <int>
    # 1     1 <dbl [4]>         2
    # 2     2 <dbl [4]>         1
    

    虽然我宁愿只保留长格式的数据,而不是做最后一步,除非有很好的理由使用列表列,因为这将避免使用 map*() *apply() 功能。