我有一个data.table
对象生成的这两个列表,我想对它们应用一个函数。
列表看起来与此类似:
>list1
$AA
C
1: 0.07519183
$BB
C
1: 0.7174377
$CC
C
1: 0.1620897
$DD
C
1: 0.184746
>list2
$AA
P1 P2 P3 P4 P5 P6
1: 0.04770305 0.1624142 0.2899578 0.029753 0.1070376 0.17549
$BB
P1 P2 P3 P4 P5 P6
1: 0.7174377 0.5965736 0.2561482 0.2561482 0.2561482 0.1997866
$CC
P1 P2 P3 P4 P5 P6
1: 0.0317663 0.139877 0.139877 0.05305057 0.1620897 0.2189595
$DD
P1 P2 P3 P4 P5 P6
1: 0.184746 0.4246214 0.2704228 0.1070376 0.3215871 0.1519672
我想申请的功能如下:
fun <- function(x,y){(sum(x>=y)+1)/(length(y)+1)}
我试过了:
new.list <- mapply(fun, list1, list2)
但它会出错:>= only defined for equally-sized data frames
。我可以重复list1
中的值以避免此错误,但还有另一种方法吗?
答案 0 :(得分:1)
使用mapply
本身就会很慢,因为这需要遍历每个项目并反复执行每个操作。
更快的选择是将列表展平并使用矢量化操作。
# Convert list1 to a vector
L1 <- as.vector(unlist(list1))
# Convert list2 to a matrix
L2 <- as.matrix(rbindlist(list2))
results <- (rowSums(L1 >= L2) + 1) / (ncol(L2)+1)
## Add names if needed
names(results) <- names(list2)
results
fun <- function(x, y) (sum( x[[1]] >= y) + 1) / (length(y) + 1)
results.m <- mapply(fun, list1, list2)
identical(results, results.m)
mapply
library(microbenchmark)
microbenchmark(MatrixStyle=(rowSums(L1 >= L2) + 1) / (ncol(L2)+1),
MapplyStyle=mapply(fun, list1, list2))
Unit: microseconds
expr min lq median uq max neval
MatrixStyle 9.560 11.4125 13.9925 15.2890 34.205 100
MapplyStyle 639.037 674.2595 697.1065 723.8985 5938.127 100