【问题标题】:Apply function to a row in a data.frame using dplyr使用 dplyr 将函数应用于 data.frame 中的一行
【发布时间】:2021-06-30 06:02:13
【问题描述】:

在基础R 中,我会执行以下操作:

d <- data.frame(a = 1:4, b = 4:1, c = 2:5)
apply(d, 1, which.max)

使用dplyr 我可以执行以下操作:

library(dplyr)
d %>% mutate(u = purrr::pmap_int(list(a, b, c), function(...) which.max(c(...))))

如果d 中有另一列,我需要指定它,但我希望它可以在任意数量的 if 列中工作。

从概念上讲,我想要类似的东西

pmap_int(list(everything()), ...)
pmap_int(list(.), ...)

但这显然行不通。我将如何使用dplyr 规范地解决这个问题?

【问题讨论】:

    标签: r dplyr tidyverse purrr


    【解决方案1】:

    这里有一些data.table 选项

    setDT(d)[, u := which.max(unlist(.SD)), 1:nrow(d)]
    

    或

    setDT(d)[, u := max.col(.SD, "first")]
    

    【讨论】:

      【解决方案2】:

      我们只需要将数据指定为.,因为data.frame 是list,其中列作为列表元素。如果我们包裹list(.),它就变成了一个嵌套列表

      library(dplyr)
      d %>% 
        mutate(u = pmap_int(., ~ which.max(c(...))))
      #  a b c u
      #1 1 4 2 2
      #2 2 3 3 2
      #3 3 2 4 3
      #4 4 1 5 3
      

      或者可以使用cur_data()

      d %>%
         mutate(u = pmap_int(cur_data(), ~ which.max(c(...))))
      

      或者,如果我们想使用everything(),请将其放在select 中,因为list(everything()) 不会处理应从中选择所有内容的数据

      d %>% 
         mutate(u = pmap_int(select(., everything()), ~ which.max(c(...))))
      

      或使用rowwise

      d %>%
          rowwise %>% 
          mutate(u = which.max(cur_data())) %>%
          ungroup
      # A tibble: 4 x 4
      #      a     b     c     u
      #  <int> <int> <int> <int>
      #1     1     4     2     2
      #2     2     3     3     2
      #3     3     2     4     3
      #4     4     1     5     3
      

      或者使用max.col 更有效

      max.col(d, 'first')
      #[1] 2 2 3 3
      

      或者collapse

      library(collapse)
      dapply(d, which.max, MARGIN = 1)
      #[1] 2 2 3 3
      

      可以包含在dplyr中

      d %>% 
          mutate(u = max.col(cur_data(), 'first'))
      

      【讨论】:

      • 我可以发誓我尝试过pmap_int(., ...),但总的来说cur_data() 是我最终要寻找的(也适用于其他一些用例)。谢谢!
      • 感谢亲爱的@akrun 的详尽解释。我本可以解决这个问题,但只能以一个 pmap 形式解决。您宝贵的解释让我对这种解决方案有了很多见识。非常感谢。
      • 您几乎涵盖了所有内容,没有为其他答案留下任何空间:) 酷! +1
      • 哈哈,这里忘记data.table了。谢谢提醒!我补充说:)
      • @akrun,当然。我只是懒得输入完整的函数调用,因此我将其缩写为 (., ...) 很清楚这不是正确的代码;)
      猜你喜欢
      • 2015-02-23
      • 2014-03-16
      • 2017-01-16
      • 2011-12-28
      • 2018-06-06
      • 1970-01-01
      • 2012-05-25
      • 2015-01-18
      相关资源
      最近更新 更多