列表r中的返回向量位置

时间:2016-06-13 19:43:16

标签: r list vector data-manipulation

我正在尝试确定元素来自我创建的列表中的向量。我在这里给出一个可重复的例子:

set.seed(101)
a <- runif(10, min=0, max=100)
b <- runif(10, min=0, max=100)
c <- runif(10, min=0, max=100)
d <- runif(10, min=0, max=100)

information <- list(a, b, c, d)

information.wanted <- mean(do.call(pmax, information))

获取信息的代码。脏的工作正常。我现在想要找到的是列表中的每个最大值来自的单个向量。例如,information.wanted(87.97 ...)中的值1来自信息列表中的向量b。我想创建另一段代码,给出vector.wanted来自的向量。

> information.wanted
 [1] 87.97957 95.68375 73.19726 93.16344 92.33189 91.34787 82.04361 81.42830 62.20120
[10] 92.48044

我不知道如何做到这一点。我尝试过的代码都没有让我接近。

postition.of.information.wanted <- ?? 

我希望得到这样的东西。数字向量很好。我可以在以后补充这些值。

> position.of.informaiton.wanted
[1] 2 3 ...

非常感谢任何帮助。感谢。

1 个答案:

答案 0 :(得分:3)

您需要将which.max应用于“信息”中每个元素的每个“i”索引:

f1 = function(x)
    sapply(seq_along(x[[1]]), function(i) which.max(sapply(x, "[[", i)))
f1(information)
# [1] 2 3 2 2 3 4 2 4 1 4

mapply已经提供了这种“并行”功能:

f2 = function(x)
    unlist(.mapply(function(...) which.max(c(...)), x, NULL))
f2(information)
# [1] 2 3 2 2 3 4 2 4 1 4

或者,不是以块的形式连接“信息”,而是转换为“矩阵” - 正如David Arenburg在评论中注意到的那样 - 在开始时注意到apply which.max到其行:

f3a = function(x)
    apply(do.call(cbind, x), 1, which.max)
f3a(information)
# [1] 2 3 2 2 3 4 2 4 1 4

或其专栏:

f3b = function(x)
    apply(do.call(rbind, x), 2, which.max)
f3b(information)
# [1] 2 3 2 2 3 4 2 4 1 4

另外,max.col对于“矩阵”很方便:

f4 = function(x)
    max.col(do.call(cbind, x), "first")
f4(information)
# [1] 2 3 2 2 3 4 2 4 1 4

如果它不是R,那么对元素的简单循环将同时提供which.maxmax ...但是R也会处理向量:

f5 = function(x)
{
     ans = rep_len(1L, length(x[[1]]))
     maxs = x[[1]]
     for(i in 2:length(x)) {
         wh = x[[i]] > maxs
         maxs[wh] = x[[i]][wh]
         ans[wh] = i 
    }
    ans #or '(data.frame(i = ans, val = maxs)' for both
}
f5(information)
# [1] 2 3 2 2 3 4 2 4 1 4

它必须以基准结束:

set.seed(007)
dat = replicate(13, runif(1e4), FALSE)

identical(f1(dat), f2(dat))
#[1] TRUE
identical(f2(dat), f3a(dat))
#[1] TRUE
identical(f3a(dat), f3b(dat))
#[1] TRUE
identical(f3b(dat), f4(dat))
#[1] TRUE
identical(f4(dat), f5(dat))
#[1] TRUE

microbenchmark::microbenchmark(f1(dat), f2(dat), f3a(dat), f3b(dat), f4(dat), f5(dat), do.call(pmax, dat), times = 50)
#Unit: microseconds
#               expr        min         lq       mean     median         uq        max neval  cld
#            f1(dat) 274995.963 298662.210 339279.948 318937.172 350822.539 723673.972    50    d
#            f2(dat)  94619.397 100079.205 114664.776 107479.127 114619.439 226733.260    50   c 
#           f3a(dat)  19767.925  23423.688  26382.919  25795.499  29215.839  40100.656    50  b  
#           f3b(dat)  20351.872  22829.997  28889.845  25090.446  30503.100 140311.058    50  b  
#            f4(dat)    975.102   1109.431   1546.571   1169.462   1361.733   8954.100    50 a   
#            f5(dat)   2427.665   2470.816   5299.386   2520.755   3197.793 112986.612    50 a   
# do.call(pmax, dat)   1477.618   1530.166   1627.934   1551.046   1602.898   2814.295    50 a