如何在R中向量化子集功能?

use*_*745 6 r dplyr

我对某些功能进行了向量化处理,这对使用干净的代码,避免循环和提高速度非常有用。

但是,我无法根据该函数的输入对任何将数据帧子集化的函数进行矢量化处理

例如,该函数在接收元素时效果很好

test_funct <- function(sep_wid, sep_len) {
    iris %>% filter(Sepal.Width > sep_wid & Sepal.Length < sep_len) %>% .$Petal.Width %>% sum
}

test_funct(4, 6)

# [1] 0.7 # This works nicely
Run Code Online (Sandbox Code Playgroud)

但是,当尝试提供向量作为此函数的输入时:

sep_wid_vector <- c(4, 3.5, 3)
sep_len_vector <- c(6, 6, 6.5)


test_funct(sep_wid_vector, sep_len_vector)

[1] 9.1 
Run Code Online (Sandbox Code Playgroud)

但是所需的输出是长度与输入向量相同的向量,就好像该函数在每个向量的第一个元素上运行,然后是第二个,然后是第三个元素。即

# 0.7    4.2     28.5 

Run Code Online (Sandbox Code Playgroud)

为了方便起见,这里的输出就像它们都是单独运行一样

test_funct(4, 6) # 0.7
test_funct(3.5, 6) # 4.2
test_funct(3, 6.5) # 28.5

Run Code Online (Sandbox Code Playgroud)

如何对基于输入的数据进行子集化的函数进行矢量化处理,以便可以接收矢量输入?

Tar*_*nnn 5

问题是filter需要向量输入,所以它会回收Sepal.widthSepal.length比较中的向量。

一种方法是map2purrr包中使用:

map2_dbl(sep_wid_vector, sep_len_vector, test_funct)
Run Code Online (Sandbox Code Playgroud)

当然,您可以将其包装在一个函数中。您可能还想考虑将数据框作为函数参数传入。


tho*_*hal 5

您可以使用 Vectorize

tv <- Vectorize(test_funct)

tv(sep_wid_vector, sep_len_vector)
# [1]  0.7  4.2 28.5
Run Code Online (Sandbox Code Playgroud)

这基本上是一个包装mapply。请注意,在*apply后台运行的是函数,这完全是一个循环