【问题标题】:Map a function to multiple data frames将一个函数映射到多个数据帧
【发布时间】:2018-10-03 13:33:38
【问题描述】:

我有一个函数可以在数据框中创建一个新列,在每个单元格中重复数据框的名称:

add_column_with_name <- function(x) {
    x$name <- deparse(substitute(x))
    return(x)

单独工作:

df_y <- tibble(x = c(1,2,3,4), y = c('a', 'b', 'c', 'd'))
df_y <- add_columns_with_name(df_y)
df_y
# A tibble: 4 x 3
  x y     name1
<dbl> <chr> <chr>
1     1 a     df_y 
2     2 b     df_y 
3     3 c     df_y 
4     4 d     df_y 

但是当我将函数作为参数传递给 map 以将其应用于数据框列表时,对象名称不会映射:

df_x <- tibble(x = c(5,6,7,8), y = c('e', 'f', 'g', 'h'))
df_vector <- c(df_x, df_y)
result <- map_df(df_vector, add_column_with_name) 
result

# A tibble: 8 x 3
      x y     name1  
   <dbl> <chr> <chr>  
1     5 e     .x[[i]]
2     6 f     .x[[i]]
3     7 g     .x[[i]] 
4     8 h     .x[[i]]
5     1 a     .x[[i]]
6     2 b     .x[[i]]
7     3 c     .x[[i]]
8     4 d     .x[[i]]

我还尝试了一种更优雅的方法:

result <- map_df(df_vector, ~ mutate(., name = deparse(substitute(.))))
result

# A tibble: 8 x 3
  x y     name 
<dbl> <chr> <chr>
1     5 e     .    
2     6 f     .    
3     7 g     .    
4     8 h     .    
5     1 a     .    
6     2 b     .    
7     3 c     .    
8     4 d     .

我本可以在写这篇文章的时候硬编码这些值,但我认为我错过了一些重要的东西!错误是否可能在于使用 deparse(substitute())?

谢谢

【问题讨论】:

  • 看看你的 df_vector,没有名字 df_x 和 df_y 的足迹。这很正常:c 评估它的参数。
  • 正如 Nicolas2 所暗示的,您需要一个包含命名元素的列表。如果你有一个命名列表,你可以使用imapnamed.list &lt;- list(df_x=df_x, df_y=df_x); imap(named.list, ~mutate(.x, name1 = .y))

标签: r purrr


【解决方案1】:

您可以防止 df_x 和 df_y 使用 quote 进行评估:

purrr::map_df(list(quote(df_x),quote(df_y))
         , function(x) {y <- eval(x); y$name <- as.character(x); y})
## A tibble: 8 x 3
#      x y     name 
#  <dbl> <chr> <chr>
#1     5 e     df_x 
#2     6 f     df_x 
#3     7 g     df_x 
#4     8 h     df_x 
#5     1 a     df_y 
#6     2 b     df_y 
#7     3 c     df_y 
#8     4 d     df_y

【讨论】:

    【解决方案2】:

    只要您将正确的names 用于list 元素,此解决方案就可以工作:

    df_y <- tibble(x = c(1,2,3,4), y = c('a', 'b', 'c', 'd'))
    df_x <- tibble(x = c(5,6,7,8), y = c('e', 'f', 'g', 'h'))
    
    df_list <- list(df_y, df_x) # we create the list
    
    names_list <- c("df_y", "df_x") # we need to name each element 
    
    map2(df_list, names_list, function(x,y) {x$name = y # assignment
                                             x}) 
    

    因此,您只需要创建每个data.frame 名称的向量。然后使用map2,它将一个函数映射到两个向量(x,y

    输出:

    $`df_y`
    # A tibble: 4 x 3
          x y     name 
      <dbl> <chr> <chr>
    1     1 a     df_y 
    2     2 b     df_y 
    3     3 c     df_y 
    4     4 d     df_y 
    
    $df_x
    # A tibble: 4 x 3
          x y     name 
      <dbl> <chr> <chr>
    1     5 e     df_x 
    2     6 f     df_x 
    3     7 g     df_x 
    4     8 h     df_x 
    

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 2022-01-24
      • 1970-01-01
      • 2019-10-17
      • 2017-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      相关资源
      最近更新 更多