如何为列使用范围而不是pmax / pmin的名称

艾希什·辛格(Ashish singhal)

我想在pmax / pmin中使用一定范围的列,而不是键入所有列的名称。

#sample data
foo <- data.frame(sapply(letters, function(x) x = sample(1:10,5)))

#this works
bar <- foo %>% 
    mutate(maxcol = pmax(a,b,c))

# this does not work
bar <- foo %>% 
    mutate(maxcol = pmax(a:z))

最终我也想要这样的东西

bar <- foo %>% 
    mutate_at(a:z = pmax(a:z))
r2evans

这是一个选项,可一次所有行,所有列执行一个函数调用

foo %>%
  mutate(maxcol = do.call(pmax, subset(., select = a:e)))
#    a  b c d e  f g  h  i j  k l m  n  o p q  r  s t u  v w  x  y z maxcol
# 1  1  4 9 2 4  4 1 10  2 3 10 4 7  1 10 9 8  2  8 9 5  1 9  1 10 9      9
# 2  5  2 5 3 5  2 8  8  5 8  2 3 6 10  9 3 5  8  7 4 6  9 8  5  8 3      5
# 3 10  9 6 1 7 10 6  4  4 7  6 6 2  7  5 5 4  1 10 7 3 10 5 10  1 7     10
# 4  8  1 4 8 9  3 3  9 10 1  8 5 8  4  4 8 6 10  5 2 9  5 7  7  3 1      9
# 5  2 10 2 9 8  9 9  6  7 5  9 2 5  5  7 4 2  5  4 8 4  6 6  2  9 6     10

您可以使用冒号来选择部分或全部列,甚至可以选择任意列:

foo %>%
  mutate(maxcol = do.call(pmax, subset(., select = c(a:e,g))))
#    a  b c d e  f g  h  i j  k l m  n  o p q  r  s t u  v w  x  y z maxcol
# 1  1  4 9 2 4  4 1 10  2 3 10 4 7  1 10 9 8  2  8 9 5  1 9  1 10 9      9
# 2  5  2 5 3 5  2 8  8  5 8  2 3 6 10  9 3 5  8  7 4 6  9 8  5  8 3      8
# 3 10  9 6 1 7 10 6  4  4 7  6 6 2  7  5 5 4  1 10 7 3 10 5 10  1 7     10
# 4  8  1 4 8 9  3 3  9 10 1  8 5 8  4  4 8 6 10  5 2 9  5 7  7  3 1      9
# 5  2 10 2 9 8  9 9  6  7 5  9 2 5  5  7 4 2  5  4 8 4  6 6  2  9 6     10

与其他答案(通常使用所谓的惯用方法)相比,应首选此原因,原因是:

  • 在Dom的答案中,该max函数对于框架的每一行都调用一次;没有使用R的向量化ops,效率低下,应尽可能避免;
  • akrun的回答pmax是,该帧的每一列都被调用一次,在这种情况下,这听起来可能更糟,但实际上更接近于最佳状态。我的答案最接近akrun,因为我们正在内select读取数据mutate

如果您想使用dplyr::selectover base::subset,则需要将其分解为

foo %>%
  mutate(maxcol = select(., a:e, g) %>% do.call(pmax, .))

我认为基准测试可以更好地证明这一点。使用提供的5x26框架,我们可以看到明显的改进:

set.seed(42)
foo <- data.frame(sapply(letters, function(x) x = sample(1:10,5)))
microbenchmark::microbenchmark(
  Dom = {
    foo %>% 
      rowwise() %>% 
      summarise(max= max(c_across(a:z)))
  },
  akr = {
    foo %>%
       mutate(maxcol = reduce(select(., a:z), pmax))
  },
  r2 = {
    foo %>%
      mutate(maxcol = do.call(pmax, subset(., select = a:z)))
  }
)
# Unit: milliseconds
#  expr    min      lq    mean  median      uq     max neval
#   Dom 6.6561 7.15260 7.61574 7.38345 7.90375 11.0387   100
#   akr 4.2849 4.69920 4.96278 4.86110 5.18130  7.0908   100
#    r2 2.3290 2.49285 2.68671 2.59180 2.78960  4.7086   100

让我们尝试使用稍大的5000x26:

set.seed(42)
foo <- data.frame(sapply(letters, function(x) x = sample(1:10,5000,replace=TRUE)))
microbenchmark::microbenchmark(
  Dom = {
    foo %>% 
      rowwise() %>% 
      summarise(max= max(c_across(a:z)))
  },
  akr = {
    foo %>%
       mutate(maxcol = reduce(select(., a:z), pmax))
  },
  r2 = {
    foo %>%
      mutate(maxcol = do.call(pmax, subset(., select = a:z)))
  }
)
# Unit: milliseconds
#  expr      min       lq      mean    median        uq       max neval
#   Dom 515.6437 563.6060 763.97348 811.45815 883.00115 1775.2366   100
#   akr   4.6660   5.1619  11.92847   5.74050   6.50625  293.7444   100
#    r2   2.9253   3.4371   4.24548   3.71845   4.27380   14.0958   100

最后一个无疑显示了使用的后果rowwiseakrun的答案与该答案之间的相对性能几乎等于5行,从而强化了这样的前提,即列方式要比行方式好(并且一次要快于两者)。

(也可以使用purrr::invoke,如果确实需要,尽管它不能加快速度:

library(purrr)
foo %>%
  mutate(maxcol = invoke(pmax, subset(., select = a:z)))

### microbenchmark(...)
# Unit: milliseconds
#     expr    min      lq    mean  median      uq      max neval
#      Dom 7.8292 8.40275 9.02813 8.97345 9.38500  12.4368   100
#      akr 4.9622 5.28855 8.78909 5.60090 6.11790 309.2607   100
#   r2base 2.5521 2.74635 3.01949 2.90415 3.21060   4.6512   100
#  r2purrr 2.5063 2.77510 3.11206 2.93415 3.33015   5.2403   100

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

返回具有多个列的data.frame的pmin或pmax

来自分类Dev

Python使用范围内的名称创建变量

来自分类Dev

我如何使用范围和随机名称的自动增量从其他多个表填充一个表

来自分类Dev

在列表的两个列表上使用成对的pmin()

来自分类Dev

pmin和pmax中的错误“ [..data.frame`(每个,nas [,1L])中的错误:未定义的列已选择”

来自分类Dev

pmin和pmax中的错误“ [..data.frame`(每个,nas [,1L])中的错误:未定义的列已选择”

来自分类Dev

如何为列分配名称-Oracle SQL

来自分类Dev

猪如何为列分配名称?

来自分类Dev

DRF:如何为权限组返回名称而不是ID?

来自分类Dev

r - 根据多列中的 pmin 从多列中找到对应的值

来自分类Dev

对整个列而不是一个单元格使用范围

来自分类Dev

复制粘贴列使用范围

来自分类Dev

试图突出显示列的使用范围

来自分类Dev

在缺少数据(R)的情况下,使用pmin()在r中查找最早的日期-更新

来自分类Dev

如何使用范围滑块更新值?

来自分类Dev

如何在 C# 中按范围而不是按标题名称引用数据表的列

来自分类Dev

如何为名称空间添加名称?

来自分类Dev

如何使用iplement名称路由而不是id

来自分类Dev

如何使用范围对csv文件中的列进行分组并使用python绘制直方图?

来自分类Dev

如何为函数添加名称?

来自分类Dev

使用范围

来自分类Dev

使用范围for / in

来自分类Dev

Golang的使用范围

来自分类Dev

为什么可以使用范围运算符和A类名称在B类中访问A类(公共)中的枚举?

来自分类Dev

如何为每种语言使用APP名称(从Cordova到Android)

来自分类Dev

在特定列中使用范围查找方法

来自分类Dev

如何在课程范围内使用课程名称?

来自分类Dev

如何在VBA Excel中使用我定义的范围名称?

来自分类Dev

如何在跟踪中使用动态范围名称?

Related 相关文章

  1. 1

    返回具有多个列的data.frame的pmin或pmax

  2. 2

    Python使用范围内的名称创建变量

  3. 3

    我如何使用范围和随机名称的自动增量从其他多个表填充一个表

  4. 4

    在列表的两个列表上使用成对的pmin()

  5. 5

    pmin和pmax中的错误“ [..data.frame`(每个,nas [,1L])中的错误:未定义的列已选择”

  6. 6

    pmin和pmax中的错误“ [..data.frame`(每个,nas [,1L])中的错误:未定义的列已选择”

  7. 7

    如何为列分配名称-Oracle SQL

  8. 8

    猪如何为列分配名称?

  9. 9

    DRF:如何为权限组返回名称而不是ID?

  10. 10

    r - 根据多列中的 pmin 从多列中找到对应的值

  11. 11

    对整个列而不是一个单元格使用范围

  12. 12

    复制粘贴列使用范围

  13. 13

    试图突出显示列的使用范围

  14. 14

    在缺少数据(R)的情况下,使用pmin()在r中查找最早的日期-更新

  15. 15

    如何使用范围滑块更新值?

  16. 16

    如何在 C# 中按范围而不是按标题名称引用数据表的列

  17. 17

    如何为名称空间添加名称?

  18. 18

    如何使用iplement名称路由而不是id

  19. 19

    如何使用范围对csv文件中的列进行分组并使用python绘制直方图?

  20. 20

    如何为函数添加名称?

  21. 21

    使用范围

  22. 22

    使用范围for / in

  23. 23

    Golang的使用范围

  24. 24

    为什么可以使用范围运算符和A类名称在B类中访问A类(公共)中的枚举?

  25. 25

    如何为每种语言使用APP名称(从Cordova到Android)

  26. 26

    在特定列中使用范围查找方法

  27. 27

    如何在课程范围内使用课程名称?

  28. 28

    如何在VBA Excel中使用我定义的范围名称?

  29. 29

    如何在跟踪中使用动态范围名称?

热门标签

归档