如何在某些R函数中隐式调用列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在某些R函数中隐式调用列相关的知识,希望对你有一定的参考价值。

R中有一些函数,您必须按名称显式调用列,例如pmin。我的问题是如何解决此问题,最好使用tidyverse

这里有一些示例数据。

library(tidyverse)
df <- tibble(a = c(1:5), 
             b = c(6:10), 
             d = c(11:15), 
             e = c(16:20))

# A tibble: 5 x 4
      a     b     d     e
  <int> <int> <int> <int>
1     1     6    11    16
2     2     7    12    17
3     3     8    13    18
4     4     9    14    19
5     5    10    15    20

现在,我想找到除“ e”以外的所有列的最小值。我可以这样做:

df %>% 
  mutate(min = pmin(a, b, d))

# A tibble: 5 x 5
      a     b     d     e   min
  <int> <int> <int> <int> <int>
1     1     6    11    16     1
2     2     7    12    17     2
3     3     8    13    18     3
4     4     9    14    19     4
5     5    10    15    20     5

但是如果我有很多列,并且想调用除“ e”之外的每一列而不必键入每一列的名称怎么办?我做了几次尝试,但都没有成功。我在示例中使用了列索引,但更希望在名称上排除“ e”。见下文。

df %>% 
  mutate(min = pmin(-e))

df %>% 
  mutate(min = pmin(names(. %>% select(.))[-4]))

df %>% 
  mutate(min = pmin(names(.)[-4]))

df %>% 
  mutate(min = pmin(noquote(paste0(names(.)[-4], collapse = ","))))

df %>% 
  mutate(min = pmin(!!ensyms(names(.)[-4])))

这些都不起作用,我有点茫然。

答案

使用dplyrpurrr的一个选项可能是:

df %>%
 mutate(min = exec(pmin, !!!select(., -e)))

      a     b     d     e   min
  <int> <int> <int> <int> <int>
1     1     6    11    16     1
2     2     7    12    17     2
3     3     8    13    18     3
4     4     9    14    19     4
5     5    10    15    20     5

对于那些不阅读评论的人,@ IceCreamToucan提出的一个不错的选择是仅涉及dplyr可能是:

df %>%
 mutate(min = do.call(pmin, select(., -e)))
另一答案

我们也可以将reducepmin一起使用

library(dplyr)
library(purrr)
df %>% 
   mutate(min = select(., -e) %>% 
                   reduce(pmin))
# A tibble: 5 x 5
#      a     b     d     e   min
#  <int> <int> <int> <int> <int>
#1     1     6    11    16     1
#2     2     7    12    17     2
#3     3     8    13    18     3
#4     4     9    14    19     4
#5     5    10    15    20     5

或带有syms!!!。请注意,en-前缀在从函数内部使用时使用

df %>% 
    mutate(min = pmin(!!! syms(names(.)[-4])))
# A tibble: 5 x 5
#      a     b     d     e   min
#  <int> <int> <int> <int> <int>
#1     1     6    11    16     1
#2     2     7    12    17     2
#3     3     8    13    18     3
#4     4     9    14    19     4
#5     5    10    15    20     5
另一答案

我将通过重塑长形,按组计算最小值,然后重塑为宽形来实现此目的:

df %>% 
  rowid_to_column() %>% 
  pivot_longer(cols = -c(e, rowid)) %>% 
  group_by(rowid) %>% 
  mutate(min = min(value)) %>% 
  ungroup() %>% 
  pivot_wider() %>% 
  select(-rowid, -min, min)

以上是关于如何在某些R函数中隐式调用列的主要内容,如果未能解决你的问题,请参考以下文章

C++ 为啥基类/结构构造函数不能有多个参数可以从派生中隐式调用?

scala中隐式转换之总结

Lombok 生成的构造函数不能在 SpringBootTest 中隐式自动装配

scala中隐式转换之隐式转换调用类中本不存在的方法

scala中隐式转换

为啥 PySide 会从 Signals 的类成员中隐式创建对象成员?