【问题标题】:How to use purrr when input to function is dataframe name当函数的输入是数据框名称时如何使用 purrr
【发布时间】:2021-06-21 16:39:31
【问题描述】:

我有一个函数,它有三个输入:df name x、df name y 和 term,这个函数看起来像:

function(df_x, df_y, term) {
list_ids <- df_x %>%
left_join(df_y, by = c("idx" = "idy")) %>%
distinct() %>%
pull(variable) 

another_function(a = list_ids, b = term, other_parameters = T)
 
}

我有一个包含 df_x、df_y 和术语的 tibble:

df_x       df_y        term
<chr>      <chr>       <chr>
df_123a    df_123b     term_m                       
df_123a    df_123b     term_n   
df_456a    df_456b     term_m   
df_456a    df_456b     term_n
df_789a    df_789a     term_m
df_789a    df_789b     term_n 

我想使用 map 函数来运行这个 tibble 元素的函数。但是,df 名称存储为字符,并且该函数包含 df_x 和 df_y 的左连接。我怎样才能做到这一点?

【问题讨论】:

  • 我想知道你的 tibble 中 df_x 和 df_y 的每个元素是否本身就是一个数据框。
  • 目前只是数据框的名称(不是数据框本身)

标签: r dplyr functional-programming purrr


【解决方案1】:

实现它的基本方法是使用eval(parse(text = 'string')) 使字符串调用对象名称。这是一个示例,该示例制作了一个函数来绑定数据框中的字符串调用的 dfs 行:

library(tidyverse)

df1 <- tibble(x = "a", y = 1)
df2 <- tibble(x = "b", y = 2)

dfs_to_process <- tibble(dfa = "df1", dfb = "df2")

join_dfs <- function(df1_name, df2_name) {
  
  eval(parse(text = df1_name)) %>% 
    bind_rows(eval(parse(text = df2_name)))
  
}

dfs_to_process %>% 
  mutate(result = map2(dfa, dfb, join_dfs)) %>% 
  pull(result)
#> [[1]]
#> # A tibble: 2 x 2
#>   x         y
#>   <chr> <dbl>
#> 1 a         1
#> 2 b         2

reprex package (v1.0.0) 于 2021-03-24 创建

更新

get() 函数会让这更整洁(感谢@mnist!):

join_dfs <- function(df1_name, df2_name) {
  get(df1_name) %>%
    bind_rows(get(df2_name))
}

我将保留原样,而不是编辑我的原始回复,因为如果我改变它,它基本上是相同的解决方案。

【讨论】:

    【解决方案2】:

    您可以使用pmap 并按名称从环境中检索对象

    library(dplyr)
    
    # tibble with information
    match_tib <- tibble(df_1 = c("df1", "df2"),
                        df_2 = c("df2", "df1"),
                        temp = 1:2)
    
    # dfs to join
    df1 <- tibble(a = 1:2,
                  b = 10)
    df2 <- tibble(a = 2:3,
                  c = 20)
    
    # run pmap
    purrr::pmap(match_tib, function(df_1, df_2, temp) {
      df_new <- get(df_1) %>% 
        left_join(get(df_2), by = "a")
      df_new %>% mutate(x = temp)
    })
    #> [[1]]
    #> # A tibble: 2 x 4
    #>       a     b     c     x
    #>   <int> <dbl> <dbl> <int>
    #> 1     1    10    NA     1
    #> 2     2    10    20     1
    
    
    #> [[2]]
    #> # A tibble: 2 x 4
    #>       a     c     b     x
    #>   <int> <dbl> <dbl> <int>
    #> 1     2    20    10     2
    #> 2     3    20    NA     2
    

    【讨论】:

    • get() 是一种通过字符串调用对象的更好看的方式!
    【解决方案3】:

    get() 包围你的data.frames 的名称应该可以,我认为你的map() 调用看起来像这样:

    purrr::map(
      .x = 1:nrow(my_tibble),
      .f = ~ my_function(df_x = get(my_tibble$df_x[.x]),
                         df_y = get(my_tibble$df_y[.x]),
                         term = my_tibble$term[.x])
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 2021-01-08
      相关资源
      最近更新 更多