【问题标题】:More efficient way:selecting vec from a list更有效的方法:从列表中选择 vec
【发布时间】:2012-05-10 16:50:06
【问题描述】:

假设

x = c(1, 2, 3.5, 4, 6, 7.5, 8, 9, 10, 11.5, 12) 
y = c(2.5, 6.5) 
I = split(x, findInterval(x, y))
f = function(vec, x) {
        d = pmax(outer(x, vec, "-"), 0)
        colSums(d - d^2/2)
}

我想计算每个区间的每个值中f(I[[i]], x)的值,然后找出每个区间中f(I[[i]], x )的最大值是哪个I[[i]]实际值。 有没有比这个for循环更有效的方法:

for (i in 1:length(I)) {
    max.values[[i]] = I[[i]][which.max(f(I[[i]], x))]
}

这是我想要得到的结果:

 > max.values
 [1]  2  6 10

【问题讨论】:

  • 您的第二段代码似乎出错了,因为max.values 不存在。我认为您首先需要max.values <- NULL

标签: r list function vector max


【解决方案1】:

这样更紧凑,但不知道是不是更高效...

v <- sapply(lapply(I,f,x=x),which.max)
mapply(getElement,I,v)

【讨论】:

    【解决方案2】:

    你可以的

    mapply('[', I, lapply(lapply(I, f, x), which.max))
    # 0  1  2 
    # 2  6 10
    

    以下是中间步骤:

    lapply(I, f, x)
    # $`0`
    # [1] -190.875 -142.375
    # 
    # $`1`
    # [1] -85.75 -70.75 -26.75
    # 
    # $`2`
    # [1] -9.500 -6.125 -1.625  0.375  0.375  0.000
    
    lapply(lapply(I, f, x), which.max)
    # $`0`
    # [1] 2
    # 
    # $`1`
    # [1] 3
    # 
    # $`2`
    # [1] 4
    

    【讨论】:

      【解决方案3】:

      如果您只是对删除 for 循环感兴趣。您可以通过以下方式将其替换为 lapply(.):

      max.values <- unlist( lapply( I, function(v) v[which.max(f(v, x))] ) );
      

      这只会在长度(I)很大的情况下产生影响。 为了获得更多的性能,看看你是否可以简化 f(.) 只是为了找到一个最大值。 为了获得最佳优化,您应该考虑用 C、C++ 或 Fortran 重写性能关键部分。

      当数据向量变大、存在冗长的循环或可用的数据结构不适合该任务时,

      R 可能会非常缓慢。 就像轶事一样,我写了一个“for-loop”-less R 代码,在 Wall time 2 周后被杀死(输入数组:n ~ 1e6)。 (R 代码在 n ~ 1e4 的输入上运行良好)。一个 C++ 等效代码需要 1 分钟。稍微优化的 C++ 代码耗时 10 秒...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-29
        • 2017-04-13
        • 1970-01-01
        • 2017-09-23
        • 2023-01-11
        • 1970-01-01
        • 2012-02-02
        相关资源
        最近更新 更多