0

假设我有一个清单:

> fs
[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

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

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

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

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  
4

3 回答 3

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
于 2013-04-19T18:59:14.033 回答
1

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

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
于 2013-04-19T19:31:24.027 回答
0

这是一个单行解决方案(如果 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 )
于 2013-04-19T20:43:35.847 回答