当我创建列表并使用“[]”运算符调用列表时,我得到了以下结果
x <- list(a=1:5, b=rnorm(5))
lapply(x[1], mean)
$a
[1] 3
lapply(x[2], sum)
$b
[1] 0.3653843
但是当我使用$ sign调用相同的列表时,我得到了不同的结果
> x <- list(a=1:5, b=rnorm(5))
> lapply(x$a, mean)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
[[4]]
[1] 4
[[5]]
[1] 5
> lapply(x$b, sum)
[[1]]
[1] 0.7208679
[[2]]
[1] 1.367853
[[3]]
[1] -0.5799428
[[4]]
[1] -2.186257
[[5]]
[1] 0.1597629
无法理解为什么?
答案 0 :(得分:1)
$
和[
之间存在重大差异。当$
返回list元素时,[
返回包含一个元素的列表。
> x[1]
$a
[1] 1 2 3 4 5
> x$a
[1] 1 2 3 4 5
x$a
的等效表达式为x[[1]]
。 [[
也返回列表元素。
> x[[1]]
[1] 1 2 3 4 5
由于$
和[[
都返回单个列表元素,因此您无法使用它们返回多个列表元素。但是,您可以使用[
返回包含多个元素的列表。例如,
> x[1:2]
$a
[1] 1 2 3 4 5
$b
[1] 0.3465471 0.2955350 1.1292449 1.1136643 -0.9798430
答案 1 :(得分:0)
在第一种情况下,lapply的输入是一个列表,其中一个元素等于c(1:5)或rnorm(5)。在第二种情况下,laply的输入是具有5个元素的向量。因此,mean函数分别获取每个值1,2,3,4,5
(在这种情况下不执行任何操作但返回相同的值)。
换句话说,x [1]给出一个元素的列表
> x <- list(a=1:5, b=rnorm(5))
> str(x[1])
List of 1
$ a: int [1:5] 1 2 3 4 5
然而,x $ a等于x [[“a”]]或x [[1]],并给出一个包含5个元素的向量:
str(x$a)
int [1:5] 1 2 3 4 5
答案 2 :(得分:0)
差异相对较小但非常有意义。列表a
是向量的奇特单词,其中元素不必是相同类型(int,char,logical等)。实际上,列表的组件可以是任何内容,甚至是其他列表。
使用类比:
矢量是一个盒子。适用于此框的唯一规则是框中的所有内容都属于同一类型。我们放入框中的内容(例如数字或布尔值)称为元素。
列表是一个箱子。对于crates而言,唯一的规则是我们可以将仅框和其他包装箱放入包装箱而不包含。我们放入包装箱中的物品称为组件。
为了从矢量/盒子或列表/板条箱中获取东西,我们使用三个函数(R中的所有内容都是函数),每个函数都有一些不同的含义:
[k]
。这些意味着“从向量中获取第k个元素”,或者在列表“获取列表中的第k个组件”的情况下。你可能会问有什么不同?请求向量中的元素将获得一个值(即TRUE,“john doe”,3),而从列表中请求组件可以使仅一个向量或另一个列表(在比喻:你从箱子里拿出来的唯一东西就是盒子或箱子)[[k]]
。这些意思是“从向量中获取第k个元素的内容”,或者在列表的情况下“获取第k个组件的内容”在列表中*。在向量的情况下,这些双括号不是很有用,因为向量不能包含某些东西反过来包含其他东西。在框中类比:你要求元素的内容。因为一个元素没有内容R选择返回元素本身。在列表的情况下,R转到列表中的第k个组件并返回其内容。使用类比:R转到crate拾取第k个框(或箱子)并返回所述盒子(或箱子)的内容。$
。这是一个几乎专门用于列表上下文的符号,因为它允许从列表中调用命名组件。此符号的主要好处是,它允许您引用列表中的组件,就好像它们是工作区中的变量一样。在你的例子中,有两件事情有点不对劲:
首先,lapply
是一个apply函数,它希望接收一个list
对象作为输入(即使它们没有明确说明)。您可以通过打印lapply
代码来看到这一点:
lapply
function (X, FUN, ...)
{
FUN <- match.fun(FUN)
if (!is.vector(X) || is.object(X))
X <- as.list(X)
.Internal(lapply(X, FUN))
}
请注意,输入R
的无论是否会将其转换为具有as.list
功能的列表。这意味着该函数对组件而不是元素进行操作。
在你的第一个输入
lapply(x[1], mean)
lapply(x[2], sum)
你在第二个输入
给函数一个组件(一个盒子)lapply(x$a, mean)
lapply(x$b, sum)
您正在提供功能元素。您可以看到R
如何处理每个打印的差异。 x$a
像矢量一样打印,x[1]
像列表一样打印。一旦函数接收到元素,它就会将它们转换为一个列表,假设每个元素都应该是列表中的一个组件,如下面的函数所示:
as.list(x$a)
其中新列表中的每个组件都是具有1个元素的向量。
tl; dr:不要混淆组件和元素:)。