R按其值填充列表

时间:2013-04-19 18:43:49

标签: r list for-loop sapply

说我有一个清单:

> 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]]的{​​{1}}值应为myFunction等等。

我希望这很清楚。什么是正确的方法呢?对于循环? * applys?我的最后一次尝试,[[3]]为空:

1-3

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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 )