如何理解r中的列表(列表(对象))?

时间:2013-11-29 14:38:13

标签: r

列表

list("haha")
[[1]]
[1] "haha"

列表

list(list("haha"))
[[1]]
[[1]][[1]]
[1] "haha"

我无法理解list(list("haha"))的输出,在我的意见中输出应为:

list(list("haha"))
[[1]]
[[1]]
[1] "haha"

这里有什么魔力?

3 个答案:

答案 0 :(得分:2)

我同意格式看起来很奇怪但是一旦你开始在列表中放置多个对象就更有意义了,那么它就不那么多余了:

> L<-list(list("haha", "hoho"), list("heehee", "guffaw"))
> L
    [[1]]
    [[1]][[1]]
    [1] "haha"

    [[1]][[2]]
    [1] "hoho"


    [[2]]
    [[2]][[1]]
    [1] "heehee"

    [[2]][[2]]
    [1] "guffaw"
为@gung添加了

编辑: 我不确定这会解决你的观点吗?但你所看到的就是你得到的。像这样......

> L[[1]][[2]]
[1] "hoho"
L[[2]][[1]]
[1] "heehee"

虽然我猜它可能不那么冗长???

为@Henrik添加了

编辑: 或者显然是这些:

> L<-list(first=list(x="haha", y="hoho"), second=list(a="heehee", b="guffaw"))
> L
$first
$first$x
[1] "haha"

$first$y
[1] "hoho"


$second
$second$a
[1] "heehee"

$second$b
[1] "guffaw"

答案 1 :(得分:1)

list(list("haha"))
[[1]] # the contents of the first element of the outer list
    [[1]] # the contents of the first element of the inner list
        [1] "haha" # the first (and only) element of the character vector 'haha'

最后的[1]是因为R中没有字符串;只是字符向量可能是长度为一。

[[ 1 ]]: the contents of a container. list( 1 )[[1]] is 1
[1]: an element of the container. list( 1, 2 )[1] is list(1)

列表的R打印声明 - 在我看来 - 太可怕了。所以你有两个有用的选择:

1:使用dput输出列表的代码。这对于命名或非常复杂的列表不起作用。

dput( list(list("haha")) )
list(list("haha"))

2:使用str检查列表的结构。这可能非常有用,但有时难以解释:

 str(list(list('haha')))
 List of 1
     $ :List of 1
      ..$ : chr "haha"

希望有所帮助。

答案 2 :(得分:1)

在R中,列表是有序的组件集(参见here)。它们的索引与其他数据结构(如向量)不同。考虑一下如果它是一个向量,你的第一个例子将如何看待:

> c("haha")
[1] "haha"

[1]只是枚举您的结果以便于参考。在这种情况下,[1]没有多大帮助,因为显然你的结果中只有一个元素而"haha"是第一个元素,但如果你的向量足够长,那些符号会有助于确定后者的位置。

由于您有列表,因此输出的索引(和外观)不同:

> list("haha")
[[1]]
[1] "haha"

现在您有两个1索引结果。这看起来有点模棱两可,但正如@Henrik和@Stephen Henderson指出的那样,部分原因是你的列表中只有一个组件。无论如何,[[1]]告诉您接下来是第一个组件,而[1]再简单地枚举该组件中的结果。由于只有一个组件,而这个组件只包含一个元素,因此严格来说这是不必要的,但是当列表中有更多内容时会更有用。

请注意,列表的组件和包含的元素始终编号,可通过这些编号访问。但它们也可以命名为,在这种情况下输出看起来有点不同:

> list(chuckle="haha")
$chuckle
[1] "haha"

现在[[1]]不会显示结果,但它仍然存在,您仍然可以使用它来访问列表的组件:

> l <- list(chuckle="haha")
> l$chuckle
[1] "haha"
> l[[1]]
[1] "haha"

您现在有两种选择; [[1]]仍然在那里,你是否愿意使用它,虽然它不是R默认打印出来的。另请注意,[1]仍会打印出您的结果以枚举它们。

如果我们有一个其组件包含多个元素的列表,可能更容易看到其中的一些功能:

> list(letters[1:20])
[[1]]
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"
[14] "n" "o" "p" "q" "r" "s" "t"

只有一个(未命名)组件,我们得到标准[[1]][1]枚举结果的第一个元素,由于所有结果都不适合一行,[14]有助于告诉我们"n"是第十四个元素。如果我们必须从"s"开始,那么现在比第19个元素更容易计算到"a"

如果我们有一个包含多个组件的列表怎么办?最简单的情况是将向量作为组件:

> list(c("haha", "hehe"), c("hoho", "hehheh"))
[[1]]
[1] "haha" "hehe"

[[2]]
[1] "hoho"   "hehheh"

结果准确地表明有两个组成部分。第一个组件表示为[[1]],该组件的元素是从[1]开始枚举的。清楚地显示有两个组件,以及每个组件中包含哪些元素。您可以使用它们来访问所需的元素:

> ll <- list(c("haha", "hehe"), c("hoho", "hehheh"))
> ll[[2]][2]
[1] "hehheh"

[[2]]索引第二个组件(即向量c("hoho", "hehheh")),[2]检索该向量的第二个元素。请注意,[1]仍然打印有结果,即使在这种特定情况下只能有一个元素。

对于更复杂的情况,让我们看一下列表列表,而不是向量列表

> list(list("haha", "hehe"), list("hoho", "hehheh"))
[[1]]
[[1]][[1]]
[1] "haha"

[[1]][[2]]
[1] "hehe"


[[2]]
[[2]][[1]]
[1] "hoho"

[[2]][[2]]
[1] "hehheh"

现在这是一团糟。令人困惑的是输出表示三个组件(或者至少在顶部有三个[[1]]),但尚不清楚这三个组件是什么。外部列表有两个组件,每个内部列表有两个组件。当组件是向量时,结果看起来不像这样。答案是你得到两次外部列表。结果第一行的[[1]]告诉您后面的内容来自第一个组件。在结果的下一行,[[1]][[1]]告诉您接下来是第一个组件的第一个组件(即使它只是告诉您这些结果与第一个组件有关)。以下是组件命名的样子:

> list(chuckles=list("haha", "hehe"), guffaws=list("hoho", "hehheh"))
$chuckles
$chuckles[[1]]
[1] "haha"

$chuckles[[2]]
[1] "hehe"


$guffaws
$guffaws[[1]]
[1] "hoho"

$guffaws[[2]]
[1] "hehheh"

现在可以更容易地看到它连续两次为您提供某些信息。请注意,如果您只要求一个组件会发生什么:

> lll <- list(list("haha", "hehe"), list("hoho", "hehheh"))
> lll[[1]]
[[1]]
[1] "haha"

[[2]]
[1] "hehe"

指定后我们只对第一个(外部)组件感兴趣,它没有告诉我们这是连续两次的第一个组件。但它确实指示了内部组件并枚举了包含的元素。

在您的示例中很难看到所有这些内容,因为您只有一个组件的嵌套列表,其中只包含一个仅包含一个元素的组件,并且没有一个组件被命名。尽管如此,结果表示第一个组件,然后在第一个组件(再次)内表示第一个(包含)组件,然后返回结果,并枚举第一个(实际上只有)元素:

> list(list("haha"))
[[1]]
[[1]][[1]]
[1] "haha"