【问题标题】:R populate list by its valuesR 按其值填充列表
【发布时间】:2013-04-19 18:43:48
【问题描述】:

假设我有一个清单:

> fs
[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
[1] 61.90298 58.29699 54.90104 51.70293 48.69110

我想通过使用它的值来“反向填充”列表的其余部分。示例:

[[3]] 应该具有[[4]] 对的函数值:

c( myFunction(fs[[4]][1], fs[[4]][2]), myFunction(fs[[4]][2], fs[[4]][3]), .... )

[[2]] 应具有 myFunction[[3]] 等...

我希望这很清楚。正确的方法是什么?对于循环? *适用?我的最后一次尝试,将1-3 留空:

n = length(fs)
for (i in rev(1:(n-1)))
  child_fs = fs[[i+1]]
  res = c()
  for (j in 1:(i+1))
    up = v(child_fs[j])
    do = v(child_fs[j+1])
    this_f = myFunction(up, do)
    res[j] = this_f
  fs[[i]] = res  

【问题讨论】:

  • 我认为如果您显示所需的输出会更清楚。

标签: r list for-loop sapply


【解决方案1】:

使fs 易于重现

fs <- list(NULL, NULL, NULL, c(61.90298, 58.29699, 54.90104, 51.70293, 48.69110))

为了能够展示一个例子,做一个琐碎的myFunction

myFunction <- function(a, b) {a + b}

您可以遍历fs 中除最后一个位置之外的所有位置(以相反的顺序),并计算每个位置。只需使用向量调用myFunciton,这些向量是下一个更高位置的向量,没有最后一个元素,也没有第一个元素。

for (i in rev(seq_along(fs))[-1]) {
  fs[[i]] <- myFunction(head(fs[[i+1]], -1), tail(fs[[i+1]], -1))
}

假设myFunction 是向量化的(给定输入向量,将给出输出向量)。如果不是,您可以轻松制作一个版本。

myFunction <- function(a, b) {a[[1]] + b[[1]]}

for (i in rev(seq_along(fs))[-1]) {
  fs[[i]] <- Vectorize(myFunction)(head(fs[[i+1]], -1), tail(fs[[i+1]], -1))
}

无论哪种情况,你都会得到

> fs
[[1]]
[1] 453.2 426.8

[[2]]
[1] 233.398 219.802 206.998

[[3]]
[1] 120.200 113.198 106.604 100.394

[[4]]
[1] 61.90298 58.29699 54.90104 51.70293 48.69110

【讨论】:

    【解决方案2】:

    真的,你所拥有的是一个起点

    start <- c(61.90298, 58.29699, 54.90104, 51.70293, 48.69110)
    

    一个你想应用的函数(我做了这个,它在所有地方添加 1 并删除最后一个元素)

    myFunction <- function(x) head(x + 1, -1L)
    

    以及你想要应用函数的次数(递归):

    n <- 3L
    

    所以我会编写一个函数来递归地应用函数n 次,然后反转输出列表:

    apply.n.times <- function(fun, n, x)
       if (n == 0L) list(x) else c(list(x), Recall(fun, n - 1L, fun(x)))
    
    rev(apply.n.times(myFunction, n, start))
    
    # [[1]]
    # [1] 64.90298 61.29699
    # 
    # [[2]]
    # [1] 63.90298 60.29699 56.90104
    # 
    # [[3]]
    # [1] 62.90298 59.29699 55.90104 52.70293
    # 
    # [[4]]
    # [1] 61.90298 58.29699 54.90104 51.70293 48.69110
    

    【讨论】:

      【解决方案3】:

      这是一个单行解决方案(如果 myFunction 可以替换为 sum 之类的东西,或者在本例中为 rowSums):

      Reduce( function(x,y) rowSums( embed(y,2) ), fs, right=TRUE, accumulate=TRUE )
      

      如果 myFunction 需要接受 2 个值并对其进行处理,则可以将其扩展为:

      Reduce( function(x,y) apply( embed(y,2), 1, function(z) myFunction(z[1],z[2]) ), 
          fs, right=TRUE, accumulate=TRUE )
      

      【讨论】:

        猜你喜欢
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多