【问题标题】:Re-creating tibbles within purrr::map在 purrr::map 中重新创建小标题
【发布时间】:2020-10-25 21:23:26
【问题描述】:

我想使用 map 将函数应用于 tibble 的每一列。 但是,我不希望简化 tibble 列。 我可以通过使用imap 用一列重新创建小标题来解决这个问题。 但是,我该怎么做呢?

让我们使用一个名为test 的超简单函数来看看它是否有效。

默认行为:列简化为向量:

test<-function(data){
  data
}

tibble(v1=1:20,v2=100:119) %>% map(test)
$v1
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

$v2
 [1] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

这行不通,因为需要引用名称:

tibble(v1=1:20,v2=100:119) %>% imap(~test(tibble(.y=.x))) %>% str
List of 2
 $ v1: tibble [20 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ .y: int [1:20] 1 2 3 4 5 6 7 8 9 10 ...
 $ v2: tibble [20 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ .y: int [1:20] 100 101 102 103 104 105 106 107 108 109 ...

那么为什么这不起作用呢?

tibble(v1=1:20,v2=100:119) %>% imap(~test(tibble(!!!(.y)=.x)))
Error: unexpected '=' in "tibble(v1=1:20,v2=100:119) %>% imap(~test(tibble(!!!(.y)="

【问题讨论】:

    标签: r purrr


    【解决方案1】:

    我们可以将 = 更改为赋值运算符 (:=) 并在 := 的 lhs 上评估 (!!) .y

    library(tibble)
    library(purrr)
    out <- tibble(v1=1:20,v2=100:119) %>% 
            imap( ~ test(tibble(!!.y := .x)))
    

    -输出

    str(out)
    #List of 2
    # $ v1: tibble [20 × 1] (S3: tbl_df/tbl/data.frame)
    #  ..$ v1: int [1:20] 1 2 3 4 5 6 7 8 9 10 ...
    # $ v2: tibble [20 × 1] (S3: tbl_df/tbl/data.frame)
    #  ..$ v2: int [1:20] 100 101 102 103 104 105 106 107 108 109 ...
    

    【讨论】:

      【解决方案2】:

      你可以使用setNames

      tibble::tibble(v1=1:20,v2=100:119) %>% purrr::imap(~test(.x) %>% setNames(.y))
      
      #$v1
      # A tibble: 20 x 1
      #      v1
      #   <int>
      # 1     1
      # 2     2
      # 3     3
      # 4     4
      # 5     5
      #...
      #...
      
      #$v2
      # A tibble: 20 x 1
      #      v2
      #   <int>
      # 1   100
      # 2   101
      # 3   102
      # 4   103
      # 5   104
      # 6   105
      #...
      #...
      

      【讨论】:

      • 谢谢。但是,如果 test() 要求其输入是 tibble(而不是向量),这将无济于事。
      • 如果 test() 要求输入是 tibble 则 imapmap 都无济于事,因为它们都会将列转换为向量。我不认为setNames 在这里会成为问题。
      • 好吧..那我不太明白你的评论。也许如果您可以显示您期望的输出或提供我的答案失败的示例,我可以更新我的答案。
      • 使用(不可否认)非常做作的函数test&lt;-function(data){glue::glue("Average: {colMeans(data)} in variable variable called {colnames(data)[1]}")} - akrun 的代码可以正常工作。
      • @Inferrator 那是因为在他的回答中明确创建了 tibble。如果您将我的答案更改为tibble::tibble(v1=1:20,v2=100:119) %&gt;% purrr::imap(~test(tibble(.x) %&gt;% setNames(.y))),它会以类似方式工作。
      猜你喜欢
      • 2021-12-18
      • 1970-01-01
      • 2019-01-17
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多