【问题标题】:Iterate over data frame by elements of a list按列表元素迭代数据帧
【发布时间】:2020-05-09 23:08:49
【问题描述】:

我正在尝试基于公共 ID 的子集合并两个数据帧。让我演示一下:

library(tidyverse)
set.seed(42)

df = list(id = c(1,2,3,4,1,2,2,2,1,1),
       group = c("A","A","A","A","B","B","B","B","C","C"),
       val = c(round(rnorm(10,6,6),0))
       ) %>% 
        tbl_df()

df_na = list(id = c(1,1,1,2,3,3,4,5,5,5),
       group = c(rep(NA,10)),
       val = c(rep(NA,10))
       ) %>% 
        tbl_df()

df 包含数据和ids,而df_na 仅包含ids 和NAs。我想创建一个包含df 的所有信息的组合数据框,并通过groupid 添加NAs,即为df 中的每个group 找到哪个ids dfdf_na 中都存在并合并。

如果我手动执行此操作,即组对组,我会使用如下内容:

A_dist = df %>% filter(group=="A") %>%
  distinct(id) %>%
  pull() 

df_A_comb = df_na %>% 
  filter(id %in% A_dist) %>%
  bind_rows(filter(df, group=="A"))

# A tibble: 11 x 3
      id group   val
   <dbl> <chr> <dbl>
 1     1 NA       NA
 2     1 NA       NA
 3     1 NA       NA
 4     2 NA       NA
 5     3 NA       NA
 6     3 NA       NA
 7     4 NA       NA
 8     1 A        14
 9     2 A         3
10     3 A         8
11     4 A        10

但很明显,我宁愿自动化这个。作为tidyverse 的新粉丝,我正在努力了解purrr::map。我可以为每个group 创建一个ids 向量。

df_dist = df %>% 
        split(.$group) %>% 
        map(distinct, id) %>% 
        map("id")

> df_dist
$A
[1] 1 2 3 4

$B
[1] 1 2

$C
[1] 1

但是翻译我的dplyr 方法更复杂,并且会在早些时候产生错误消息。

###this approach doesn't work...
df_comb = df_na %>% 
        map(filter, id %in% df_dist)# %>% 
        ...

Error in UseMethod("filter_") : no applicable method for 'filter_' applied to an object of class "c('double', 'numeric')"

任何帮助将不胜感激!

【问题讨论】:

  • bind_rows 中调用filter 不完全确定您要做什么;只需在 map 中过滤,就像在上面的行中所做的一样。 bind_rows 可以获取一个列表,因此无论您获得什么数据帧列表,只需将其传递给 bind_rows
  • 抱歉不清楚。我对我的问题进行了一些编辑。我很早就遇到了一个错误,我不明白如何将迭代 df 中的每个 group 集成到我目前的方法中。

标签: r list dplyr iteration purrr


【解决方案1】:

tidyverse 很棒,但有时您会忽略简单索引的强大功能以及apply 系列真正有用的基本 R 工具。这个单一的lapply 函数将为您提供一个列表,其中包含您想要的指定格式的所有数据框:

lapply(unique(df$group), function(x){
  rbind(df_na[df_na$id %in% df$id[df$group == x],], df[df$group == x,])})

结果:

#> [[1]]
#> # A tibble: 11 x 3
#>       id group   val
#>    <dbl> <chr> <dbl>
#>  1     1 <NA>     NA
#>  2     1 <NA>     NA
#>  3     1 <NA>     NA
#>  4     2 <NA>     NA
#>  5     3 <NA>     NA
#>  6     3 <NA>     NA
#>  7     4 <NA>     NA
#>  8     1 A        14
#>  9     2 A         3
#> 10     3 A         8
#> 11     4 A        10
#> 
#> [[2]]
#> # A tibble: 8 x 3
#>      id group   val
#>   <dbl> <chr> <dbl>
#> 1     1 <NA>     NA
#> 2     1 <NA>     NA
#> 3     1 <NA>     NA
#> 4     2 <NA>     NA
#> 5     1 B         8
#> 6     2 B         5
#> 7     2 B        15
#> 8     2 B         5
#> 
#> [[3]]
#> # A tibble: 5 x 3
#>      id group   val
#>   <dbl> <chr> <dbl>
#> 1     1 <NA>     NA
#> 2     1 <NA>     NA
#> 3     1 <NA>     NA
#> 4     1 C        18
#> 5     1 C         6

如果您想将它们加入单个数据框,请存储结果(例如x)并执行以下操作:

do.call(rbind, x)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-31
    • 2018-01-16
    • 2018-03-12
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 2018-11-09
    相关资源
    最近更新 更多