R:使用 all() 保持函数向量化

问题描述 投票:0回答:3

我有一个功能

fun
检查多个条件
a, b
。如果满足所有条件,该函数应返回
TRUE
,否则应返回
FALSE

a = 1
b = 0

fun <- function(a, b){
  all(a < 1,
      b < 1,
      na.rm = TRUE)
}

fun(a, b)

这个函数就可以解决问题。但是,如果我现在使用向量,

all()
当然不会保留向量形式,而是返回单个
TRUE
FALSE

我想要一个与以下功能相同的功能:

a = 1:2
b = 0:1

funV <- function(a, b){
  a < 1 & b < 1
}

funV(a, b)

但没有链接

&
并且它也应该适用于缺失值。

r vectorization
3个回答
5
投票

pmin
+
as.logical
= 矢量化
all()

fun <- function(a, b){
  as.logical(pmin(a < 1, b < 1, na.rm = TRUE))
}

fun(1:2, 0:1)
# [1] FALSE FALSE

基准

# Unit: milliseconds
#              expr        min         lq       mean     median         uq        max neval
#    pmin_all(a, b)   1.816587   1.843934   2.223257   1.868905   3.004286   5.936595   100
#  mapply_all(a, b) 181.204836 183.868243 188.579629 185.331190 188.332364 347.997674   100
#     vec_all(a, b) 186.911905 190.187575 194.159146 192.135094 194.848294 218.416740   100
pmin_all <- function(a, b){
  as.logical(pmin(a < 1, b < 1, na.rm = TRUE))
}

mapply_all <- function(a, b){
  mapply(\(x, y) all(x < 1, y < 1, na.rm = TRUE), a, b)
}

vec_all <- Vectorize(function(a, b){
  all(a < 1, b < 1, na.rm = TRUE)
})

a <- rnorm(1e5, mean = 1)
b <- rnorm(1e5, mean = 1)

library(microbenchmark)

bm <- microbenchmark(
  pmin_all(a, b),
  mapply_all(a, b),
  vec_all(a, b),
  check = 'identical'
)

3
投票

我们可以使用

Vectorize()
来创建一个向量化函数。
Vectorize()
在底层使用
mapply()

fun <- function(a,b){
  all(a < 1,
      b < 1,
      na.rm = TRUE)
}

a = 1:2
b = 0:1

funV <- Vectorize(fun)

funV(a,b)
#> [1] FALSE FALSE

reprex 包于 2023 年 2 月 14 日创建(v2.0.1)


3
投票

mapply

fun <- function(a,b){
  mapply(\(x, y) all(x < 1, y < 1, na.rm = TRUE), a, b)
}

fun(1:2, 0:1)
#[1] FALSE FALSE
© www.soinside.com 2019 - 2024. All rights reserved.