R:列表中的向量和外部向量之间的操作

时间:2016-06-01 15:37:13

标签: r list vector

Supose我有一个包含3个元素的列表,每个元素是另外2个元素的列表。第一个是4维向量,第二个是char。以下代码将完全按照我刚才描述的方式生成一个列表:

x <- NULL
for(i in 1:3){
  set.seed(i); a <- list(sample(1:4, 4, replace = T), LETTERS[i])
  x <- c(x, list(a))
}

它的结构是以下类型的(由于我使用了示例函数,确切的值可能会变化):

> str(x)
List of 3
 $ :List of 2
  ..$ : int [1:4] 2 2 3 4
  ..$ : chr "A"
 $ :List of 2
  ..$ : int [1:4] 1 3 3 1
  ..$ : chr "B"
 $ :List of 2
  ..$ : int [1:4] 1 4 2 2
  ..$ : chr "C"

现在,我有另一个4维向量,比如y

y <- 1:4

最后,我想创建一个矩阵,该矩阵由y与列表中存储的每个4维向量之间的操作(比如总和)产生。对于给定的示例,此矩阵将给出以下结果:

     [,1] [,2] [,3]
[1,]    3    2    2
[2,]    4    5    6
[3,]    6    6    5
[4,]    8    5    6

问题:如何以简单而优雅的方式创建上述矩阵?我正在寻找一些可以使用某些apply函数的解决方案,或者可以以某种我不知道的方式直接使用sum函数。

1 个答案:

答案 0 :(得分:3)

试试这个:

# you can also simply write: sapply(x, function(x) x[[1]]) + y
foo <- function(x)  x[[1]]
sapply(x, foo) + y
  • 函数foo提取列表中的向量;
  • sapply将这些向量作为矩阵返回;
  • 最后,我们使用回收规则进行添加。

更新1

好吧,因为@Frank提到了它。我可能会做一点解释。 R中的'[['运算符(注意引用!)是一个函数,带有两个参数。第一个是矢量类型对象,如矢量/列表;而第二个是您想要引用的索引。对于以下示例:

a <- 1:4
a[2]  # 2
'[['(a, 2)  # 2

虽然我的原始答案更容易理解,但它并不是最有效的,因为对于每个列表元素,都会调用两个函数调用来取出向量。如果我们直接使用'[[',则只调用一个函数调用。因此,我们通过减少函数调用开销来节省时间。当函数很小并且没有太多工作时,函数调用开销会很明显。

R中的运算符本质上是函数。 +*等是算术运算符,您可以通过?'+'找到它们。同样,您可以找到?'[['。如果你现在无法做到这一点,请不要太担心。迟早你会得到它。

更新2

  

我不明白它是如何完成这项工作的。当我只是在控制台上询问[[1]]时,我得到列表的第一个元素(整数向量和char值),而不仅仅是向量。我猜其余部分应该是sapply函数的魔力。

啊,如果您难以理解sapply(或类似lapply),请考虑以下事项。但我会从lapply开始。

output <- lapply(x, foo)正在执行以下操作:

output <- vector("list", length = length(x))
for (i in 1:length(x)) output[[i]] <- foo(x[[i]])

所以lapply返回一个列表:

> output
[[1]]
[1] 2 2 3 4

[[2]]
[1] 1 4 4 3

[[3]]
[1] 3 1 1 1

是的,lapply遍历x的元素,应用函数foo,并将结果返回到另一个列表中。

sapply采用了类似的想法,但返回了一个向量/矩阵。您可能认为sapplylapply的结果折叠为矢量/矩阵。

当然,我的这部分解释只是为了让事情变得可以理解。 lapplysapply并未真正实现为R循环。它们更有效率。