如何在dplyr中对比列与列表时避免使用rowwise?
不用rowwise实现统计的方法
当然有,以下是几种高效的替代方案:
方法1:基础R的sapply遍历
利用sapply逐个处理df$x的元素,计算normvec中小于等于该元素的数量:
normvec <- rnorm(20) df <- data.frame(x=abs(rnorm(50)), col1=1:50) df$nsmaller <- sapply(df$x, function(val) sum(normvec <= val))
方法2:向量化操作——outer+行求和
通过outer生成两两比较的布尔矩阵,再对每行求和,这种向量化操作效率更高:
normvec <- rnorm(20) df <- data.frame(x=abs(rnorm(50)), col1=1:50) df$nsmaller <- rowSums(outer(df$x, normvec, `<=`))
方法3:tidyverse框架下的map_dbl
如果习惯用tidyverse语法,用purrr的map_dbl替代rowwise:
library(dplyr) library(purrr) normvec <- rnorm(20) df <- data.frame(x=abs(rnorm(50)), col1=1:50) %>% mutate(nsmaller = map_dbl(x, ~sum(normvec <= .x)))
方法4:排序后用findInterval(大数据量首选)
先对normvec排序,再用findInterval定位每个x的位置,位置值即为小于等于x的元素数量,这种方法时间复杂度更低,适合大规模数据:
normvec <- rnorm(20) sorted_norm <- sort(normvec) df <- data.frame(x=abs(rnorm(50)), col1=1:50) %>% mutate(nsmaller = findInterval(x, sorted_norm, rightmost.closed = TRUE))
内容的提问来源于stack exchange,提问作者Algorithman
相关产品推荐
相关产品推荐

