list 如何在 R 中正确使用列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2050790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:26:44  来源:igfitidea点击:

How to Correctly Use Lists in R?

rlistdata-structureslanguage-featuresabstract-data-type

提问by doug

Brief background: Many (most?) contemporary programming languages in widespread use have at least a handful of ADTs [abstract data types] in common, in particular,

简要背景:许多(大多数?)当代广泛使用的编程语言至少有少数共同的 ADT [抽象数据类型],特别是,

  • string(a sequence comprised of characters)

  • list(an ordered collection of values), and

  • map-based type(an unordered array that maps keys to values)

  • 字符串(由字符组成的序列)

  • 列表(有序的值集合),以及

  • 基于映射的类型(将键映射到值的无序数组)

In the R programming language, the first two are implemented as characterand vector, respectively.

在 R 编程语言中,前两个分别实现为charactervector

When I began learning R, two things were obvious almost from the start: listis the most important data type in R (because it is the parent class for the R data.frame), and second, I just couldn't understand how they worked, at least not well enough to use them correctly in my code.

当我开始学习 R 时,有两件事几乎从一开始list就很明显:是 R 中最重要的数据类型(因为它是 R 的父类data.frame),其次,我就是不明白它们是如何工作的,至少不足以在我的代码中正确使用它们。

For one thing, it seemed to me that R's listdata type was a straightforward implementation of the map ADT (dictionaryin Python, NSMutableDictionaryin Objective C, hashin Perl and Ruby, object literalin Javascript, and so forth).

一方面,在我看来,R 的list数据类型是映射 ADT 的直接实现(dictionary在 Python、NSMutableDictionaryObjective C、hashPerl 和 Ruby、object literalJavascript 等中)。

For instance, you create them just like you would a Python dictionary, by passing key-value pairs to a constructor (which in Python is dictnot list):

例如,您可以像创建 Python 字典一样创建它们,方法是将键值对传递给构造函数(在 Python 中dict不是list):

x = list("ev1"=10, "ev2"=15, "rv"="Group 1")

And you access the items of an R List just like you would those of a Python dictionary, e.g., x['ev1']. Likewise, you can retrieve just the 'keys'or just the 'values'by:

并且您可以像访问 Python 字典一样访问 R 列表的项目,例如,x['ev1']. 同样,您可以通过以下方式仅检索“键”“值”

names(x)    # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"

unlist(x)   # fetch just the 'values' of an R list
#   ev1       ev2        rv 
#  "10"      "15" "Group 1" 

x = list("a"=6, "b"=9, "c"=3)  

sum(unlist(x))
# [1] 18

but R lists are also unlikeother map-type ADTs (from among the languages I've learned anyway). My guess is that this is a consequence of the initial spec for S, i.e., an intention to design a data/statistics DSL [domain-specific language] from the ground-up.

但是 Rlist不同于其他地图类型的 ADT(无论如何我都学过这些语言)。我的猜测是,这是 S 初始规范的结果,即打算从头开始设计数据/统计 DSL [领域特定语言]。

threesignificant differences between R lists and mapping types in other languages in widespread use (e.g,. Python, Perl, JavaScript):

Rlist和其他广泛使用的语言(例如,Python、Perl、JavaScript)中的映射类型之间的三个显着差异:

first, lists in R are an orderedcollection, just like vectors, even though the values are keyed (ie, the keys can be any hashable value not just sequential integers). Nearly always, the mapping data type in other languages is unordered.

首先listR 中的 s 是有序集合,就像向量一样,即使值是键控的(即,键可以是任何可散列的值,而不仅仅是连续整数)。几乎总是,其他语言中的映射数据类型是unordered

second, lists can be returned from functions even though you never passed in a listwhen you called the function, and even thoughthe function that returned the listdoesn't contain an (explicit) listconstructor (Of course, you can deal with this in practice by wrapping the returned result in a call to unlist):

其次list即使您在list调用函数时从未传入 a ,也可以从函数返回 s ,即使返回 的list函数不包含(显式)list构造函数(当然,您可以在实践中通过将返回的结果包装在对unlist)的调用中:

x = strsplit(LETTERS[1:10], "")     # passing in an object of type 'character'

class(x)                            # returns 'list', not a vector of length 2
# [1] list

A thirdpeculiar feature of R's lists: it doesn't seem that they can be members of another ADT, and if you try to do that then the primary container is coerced to a list. E.g.,

一个第三讨论R的独特功能listS:它似乎并不认为他们可以是另一种ADT的成员,如果你尝试这样做,那么主容器被裹挟到list。例如,

x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)

class(x)
# [1] list

my intention here is not to criticize the language or how it is documented; likewise, I'm not suggesting there is anything wrong with the listdata structure or how it behaves. All I'm after is to correct is my understanding of how they work so I can correctly use them in my code.

我在这里的目的不是批评语言或它是如何记录的;同样,我并不是在暗示list数据结构或它的行为方式有什么问题。我所追求的只是纠正我对它们如何工作的理解,以便我可以在我的代码中正确使用它们。

Here are the sorts of things I'd like to better understand:

以下是我想更好地理解的事情:

  • What are the rules which determine when a function call will return a list(e.g., strsplitexpression recited above)?

  • If I don't explicitly assign names to a list(e.g., list(10,20,30,40)) are the default names just sequential integers beginning with 1? (I assume, but I am far from certain that the answer is yes, otherwise we wouldn't be able to coerce this type of listto a vector w/ a call to unlist.)

  • Why do these two different operators, [], and [[]], return the sameresult?

    x = list(1, 2, 3, 4)

    both expressions return "1":

    x[1]

    x[[1]]

  • why do these two expressions notreturn the same result?

    x = list(1, 2, 3, 4)

    x2 = list(1:4)

  • 确定函数调用何时返回 a list(例如,strsplit上面提到的表达式)的规则是什么?

  • 如果我没有明确地为 a list(eg, list(10,20,30,40))分配名称,那么默认名称是否只是以 1 开头的连续整数?(我假设,但我不确定答案是肯定的,否则我们将无法将这种类型强制list转换为带有对unlist.的调用的向量。)

  • 为什么这两个不同的运算符 ,[][[]]返回相同的结果?

    x = list(1, 2, 3, 4)

    两个表达式都返回“1”:

    x[1]

    x[[1]]

  • 为什么这两个表达式返回相同的结果?

    x = list(1, 2, 3, 4)

    x2 = list(1:4)

Please don't point me to the R Documentation (?list, R-intro)--I have read it carefully and it does not help me answer the type of questions I recited just above.

请不要将我指向 R 文档 ( ?list, R-intro)——我已经仔细阅读了它,但它并不能帮助我回答上面提到的问题类型。

(lastly, I recently learned of and began using an R Package (available on CRAN) called hashwhich implements conventionalmap-type behavior via an S4 class; I can certainly recommend this Package.)

(最后,我最近了解到并开始使用 R 包(在 CRAN 上可用)hash,它通过 S4 类实现传统的地图类型行为;我当然可以推荐这个包。)

采纳答案by Shane

Just to address the last part of your question, since that really points out the difference between a listand vectorin R:

只是为了解决您问题的最后一部分,因为这确实指出了 alistvectorR 中的区别:

Why do these two expressions not return the same result?

x = list(1, 2, 3, 4); x2 = list(1:4)

为什么这两个表达式不返回相同的结果?

x = 列表(1, 2, 3, 4); x2 = 列表(1:4)

A list can contain any other class as each element. So you can have a list where the first element is a character vector, the second is a data frame, etc. In this case, you have created two different lists. xhas four vectors, each of length 1. x2has 1 vector of length 4:

列表可以包含任何其他类作为每个元素。所以你可以有一个列表,其中第一个元素是一个字符向量,第二个元素是一个数据框,等等。在这种情况下,你已经创建了两个不同的列表。 x有四个向量,每个长度为 1。 x2有 1 个长度为 4 的向量:

> length(x[[1]])
[1] 1
> length(x2[[1]])
[1] 4

So these are completely different lists.

所以这些是完全不同的列表。

R lists are very much like a hash mapdata structure in that each index value can be associated with any object. Here's a simple example of a list that contains 3 different classes (including a function):

R 列表非常类似于哈希映射数据结构,因为每个索引值都可以与任何对象相关联。这是一个包含 3 个不同类(包括一个函数)的列表的简单示例:

> complicated.list <- list("a"=1:4, "b"=1:3, "c"=matrix(1:4, nrow=2), "d"=search)
> lapply(complicated.list, class)
$a
[1] "integer"
$b
[1] "integer"
$c
[1] "matrix"
$d
[1] "function"

Given that the last element is the search function, I can call it like so:

鉴于最后一个元素是搜索功能,我可以这样称呼它:

> complicated.list[["d"]]()
[1] ".GlobalEnv" ...

As a final comment on this: it should be noted that a data.frameis really a list (from the data.framedocumentation):

作为对此的最后评论:应该注意的是 adata.frame实际上是一个列表(来自data.frame文档):

A data frame is a list of variables of the same number of rows with unique row names, given class ‘"data.frame"'

数据框是具有唯一行名称的相同行数的变量列表,给定类 '"data.frame"'

That's why columns in a data.framecan have different data types, while columns in a matrix cannot. As an example, here I try to create a matrix with numbers and characters:

这就是为什么 a 中的列data.frame可以有不同的数据类型,而矩阵中的列不能。例如,在这里我尝试创建一个包含数字和字符的矩阵:

> a <- 1:4
> class(a)
[1] "integer"
> b <- c("a","b","c","d")
> d <- cbind(a, b)
> d
 a   b  
[1,] "1" "a"
[2,] "2" "b"
[3,] "3" "c"
[4,] "4" "d"
> class(d[,1])
[1] "character"

Note how I cannot change the data type in the first column to numeric because the second column has characters:

请注意我无法将第一列中的数据类型更改为数字,因为第二列有字符:

> d[,1] <- as.numeric(d[,1])
> class(d[,1])
[1] "character"

回答by Dirk Eddelbuettel

Regarding your questions, let me address them in order and give some examples:

关于你的问题,让我按顺序回答,并举一些例子:

1) A list is returned if and when the return statement adds one. Consider

1) 如果并且当 return 语句添加一个时,则返回一个列表。考虑

 R> retList <- function() return(list(1,2,3,4)); class(retList())
 [1] "list"
 R> notList <- function() return(c(1,2,3,4)); class(notList())
 [1] "numeric"
 R> 

2) Names are simply not set:

2) 名称根本没有设置:

R> retList <- function() return(list(1,2,3,4)); names(retList())
NULL
R> 

3) They do not return the same thing. Your example gives

3)他们不返回相同的东西。你的例子给出

R> x <- list(1,2,3,4)
R> x[1]
[[1]]
[1] 1
R> x[[1]]
[1] 1

where x[1]returns the first element of x-- which is the same as x. Every scalar is a vector of length one. On the other hand x[[1]]returns the first element of the list.

wherex[1]返回 -- 的第一个元素,xx. 每个标量都是一个长度为 1 的向量。另一方面x[[1]]返回列表的第一个元素。

4) Lastly, the two are different between they create, respectively, a list containing four scalars and a list with a single element (that happens to be a vector of four elements).

4) 最后,两者的区别在于它们分别创建了一个包含四个标量的列表和一个包含单个元素的列表(恰好是一个包含四个元素的向量)。

回答by JD Long

Just to take a subset of your questions:

只是拿你的问题的一个子集:

This articleon indexing addresses the question of the difference between []and [[]].

这篇关于索引的文章解决了[]和之间的区别问题[[]]

In short [[]] selects a single item from a list and []returns a list of the selected items. In your example, x = list(1, 2, 3, 4)'item 1 is a single integer but x[[1]]returns a single 1 and x[1]returns a list with only one value.

简而言之 [[]] 从列表中选择单个项目并[]返回所选项目的列表。在您的示例中,x = list(1, 2, 3, 4)'项目 1 是一个整数,但x[[1]]返回一个 1 并x[1]返回一个只有一个值的列表。

> x = list(1, 2, 3, 4)
> x[1]
[[1]]
[1] 1

> x[[1]]
[1] 1

回答by Alex Brown

One reason lists work as they do (ordered) is to address the need for an ordered container that can contain any type at any node, which vectors do not do. Lists are re-used for a variety of purposes in R, including forming the base of a data.frame, which is a list of vectors of arbitrary type (but the same length).

列表按它们的方式工作(有序)的一个原因是为了满足对可以在任何节点包含任何类型的有序容器的需求,而矢量不这样做。列表在 R 中有多种用途,包括形成 a 的基数data.frame,它是任意类型(但长度相同)的向量列表。

Why do these two expressions not return the same result?

为什么这两个表达式不返回相同的结果?

x = list(1, 2, 3, 4); x2 = list(1:4)

To add to @Shane's answer, if you wanted to get the same result, try:

要添加到@Shane 的答案中,如果您想获得相同的结果,请尝试:

x3 = as.list(1:4)

Which coerces the vector 1:4into a list.

这将向量强制1:4转换为列表。

回答by Shane

Just to add one more point to this:

再补充一点:

R does have a data structure equivalent to the Python dict in the hashpackage. You can read about it in this blog post from the Open Data Group. Here's a simple example:

R 确实具有hash包中的 Python dict 等效的数据结构。您可以在 Open Data Group 的这篇博文中阅读相关内容。这是一个简单的例子:

> library(hash)
> h <- hash( keys=c('foo','bar','baz'), values=1:3 )
> h[c('foo','bar')]
<hash> containing 2 key-value pairs.
  bar : 2
  foo : 1

In terms of usability, the hashclass is very similar to a list. But the performance is better for large datasets.

在可用性方面,hash该类非常类似于列表。但是对于大型数据集,性能更好。

回答by Steve Lianoglou

You say:

你说:

For another, lists can be returned from functions even though you never passed in a List when you called the function, and even though the function doesn't contain a List constructor, e.g.,

另一方面,即使您在调用函数时从未传入 List,并且即使该函数不包含 List 构造函数,也可以从函数返回列表,例如,

x = strsplit(LETTERS[1:10], "") # passing in an object of type 'character'
class(x)
# => 'list'

And I guess you suggest that this is a problem(?). I'm here to tell you why it's not a problem :-). Your example is a bit simple, in that when you do the string-split, you have a list with elements that are 1 element long, so you know that x[[1]]is the same as unlist(x)[1]. But what if the result of strsplitreturned results of different length in each bin. Simply returning a vector (vs. a list) won't do at all.

我猜你认为这是一个问题(?)。我是来告诉你为什么这不是问题的:-)。您的示例有点简单,因为当您进行字符串拆分时,您有一个包含 1 个元素长的元素的列表,因此您知道它x[[1]]unlist(x)[1]. 但是如果strsplit在每个bin中返回不同长度的结果怎么办。简单地返回一个向量(相对于一个列表)根本不会做。

For instance:

例如:

stuff <- c("You, me, and dupree",  "You me, and dupree",
           "He ran away, but not very far, and not very fast")
x <- strsplit(stuff, ",")
xx <- unlist(strsplit(stuff, ","))

In the first case (x: which returns a list), you can tell what the 2nd "part" of the 3rd string was, eg: x[[3]][2]. How could you do the same using xxnow that the results have been "unraveled" (unlist-ed)?

在第一种情况下(x: 返回一个列表),您可以判断第三个字符串的第二个“部分”是什么,例如:x[[3]][2]xx既然结果已经“解开”(unlist-ed),你怎么能做同样的事情?

回答by JeremyS

x = list(1, 2, 3, 4)
x2 = list(1:4)
all.equal(x,x2)

is not the same because 1:4 is the same as c(1,2,3,4). If you want them to be the same then:

不一样,因为 1:4 与 c(1,2,3,4) 相同。如果您希望它们相同,则:

x = list(c(1,2,3,4))
x2 = list(1:4)
all.equal(x,x2)

回答by nicola

This is a very old question, but I think that a new answer might add some value since, in my opinion, no one directly addressed some of the concerns in the OP.

这是一个非常古老的问题,但我认为新的答案可能会增加一些价值,因为在我看来,没有人直接解决 OP 中的一些问题。

Despite what the accepted answers suggests, listobjects in R are nothash maps. If you want to make a parallel with python, listare more like, you guess, python lists (or tuples actually).

尽管接受的答案暗示了什么list,R 中的对象不是哈希映射。如果你想与 python 平行list,你猜更像是 python lists(或者tuple实际上是 s)。

It's better to describe how most R objects are stored internally (the C type of an R object is SEXP). They are made basically of three parts:

最好描述大多数 R 对象是如何在内部存储的(R 对象的 C 类型是SEXP)。它们基本上由三部分组成:

  • an header, which declares the R type of the object, the length and some other meta data;
  • the data part, which is a standard C heap-allocated array (contiguous block of memory);
  • the attributes, which are a named linked list of pointers to other R objects (or NULLif the object doesn't have attributes).
  • 一个标头,它声明了对象的 R 类型、长度和其他一些元数据;
  • 数据部分,这是一个标准的 C 堆分配数组(连续的内存块);
  • 属性,它们是指向其他 R 对象(或者NULL如果对象没有属性)的指针的命名链接列表。

From an internal point of view, there is little difference between a listand a numericvector for instance. The values they store are just different. Let's break two objects into the paradigm we described before:

例如,从内部的角度来看,alistnumeric向量之间几乎没有区别。它们存储的值只是不同。让我们将两个对象分解为我们之前描述的范式:

x <- runif(10)
y <- list(runif(10), runif(3))

For x:

对于x

  • The header will say that the type is numeric(REALSXPin the C-side), the length is 10 and other stuff.
  • The data part will be an array containing 10 doublevalues.
  • The attributes are NULL, since the object doesn't have any.
  • 标题会说类型是numericREALSXP在 C 端),长度是 10 和其他东西。
  • 数据部分将是一个包含 10 个double值的数组。
  • 属性是NULL,因为对象没有任何属性。

For y:

对于y

  • The header will say that the type is list(VECSXPin the C-side), the length is 2 and other stuff.
  • The data part will be an array containing 2 pointers to two SEXP types, pointing to the value obtained by runif(10)and runif(3)respectively.
  • The attributes are NULL, as for x.
  • 标题会说类型是listVECSXP在 C 端),长度是 2 和其他东西。
  • 数据部分将是一个包含 2 个指向两个 SEXP 类型的指针的数组,分别指向runif(10)和获得的值runif(3)
  • 属性是NULL,至于x

So the only difference between a numericvector and a listis that the numericdata part is made of doublevalues, while for the listthe data part is an array of pointers to other R objects.

所以numeric向量和 a之间的唯一区别listnumeric数据部分由double值组成,而list数据部分是指向其他 R 对象的指针数组。

What happens with names? Well, names are just some of the attributes you can assign to an object. Let's see the object below:

名字会发生什么?好吧,名称只是您可以分配给对象的一些属性。让我们看看下面的对象:

z <- list(a=1:3, b=LETTERS)
  • The header will say that the type is list(VECSXPin the C-side), the length is 2 and other stuff.
  • The data part will be an array containing 2 pointers to two SEXP types, pointing to the value obtained by 1:3and LETTERSrespectively.
  • The attributes are now present and are a namescomponent which is a characterR object with value c("a","b").
  • 标题会说类型是listVECSXP在 C 端),长度是 2 和其他东西。
  • 数据部分将是一个包含 2 个指向两个 SEXP 类型的指针的数组,分别指向1:3和获得的值LETTERS
  • 属性现在存在并且是一个names组件,它是一个character具有 value的R 对象c("a","b")

From the R level, you can retrieve the attributes of an object with the attributesfunction.

从 R 级别,您可以使用该attributes函数检索对象的属性。

The key-value typical of an hash map in R is just an illusion. When you say:

R 中散列映射的典型键值只是一种错觉。当你说:

z[["a"]]

this is what happens:

这是发生的事情:

  • the [[subset function is called;
  • the argument of the function ("a") is of type character, so the method is instructed to search such value from the namesattribute (if present) of the object z;
  • if the namesattribute isn't there, NULLis returned;
  • if present, the "a"value is searched in it. If "a"is not a name of the object, NULLis returned;
  • if present, the position is determined (1 in the example). So the first element of the list is returned, i.e. the equivalent of z[[1]].
  • [[子集函数被调用;
  • 函数 ( "a")的参数是 type character,因此指示该方法从对象的names属性(如果存在)中搜索此类值z
  • 如果names属性不存在,NULL则返回;
  • 如果存在,"a"则在其中搜索该值。如果"a"不是对象名称,NULL则返回;
  • 如果存在,则确定位置(示例中为 1)。所以返回列表的第一个元素,即相当于z[[1]].

The key-value search is rather indirect and is always positional. Also, useful to keep in mind:

键值搜索是相当间接的,并且始终是定位的。此外,请记住:

  • in hash maps the only limit a key must have is that it must be hashable. namesin R must be strings (charactervectors);
  • in hash maps you cannot have two identical keys. In R, you can assign namesto an object with repeated values. For instance:

    names(y) <- c("same", "same")
    

    is perfectly valid in R. When you try y[["same"]]the first value is retrieved. You should know why at this point.

  • 在哈希映射的唯一限制的关键必须是,它必须是可哈希names在 R 中必须是字符串(character向量);
  • 在哈希映射中,您不能有两个相同的键。在 R 中,您可以分配names给具有重复值的对象。例如:

    names(y) <- c("same", "same")
    

    在 R 中完全有效。当您尝试y[["same"]]检索第一个值时。你应该知道为什么在这一点上。

In conclusion, the ability to give arbitrary attributes to an object gives you the appearance of something different from an external point of view. But R lists are not hash maps in any way.

总而言之,赋予对象任意属性的能力使您从外部的角度来看具有不同的外观。但是 Rlist无论如何都不是哈希映射。

回答by Petr Matousu

Alhough this is pretty old question I must say it is touching exactly the knowledge I was missing during my first steps in R - i.e. how to express data in my hand as object in R or how to select from existing objects. It is not easy for a R novice to think "in a R box" from the very beginning.

尽管这是一个很老的问题,但我必须说它正好触及了我在 R 的第一步中所缺少的知识 - 即如何将我手中的数据表示为 R 中的对象或如何从现有对象中进行选择。R 新手从一开始就“在 R 盒中”思考并不容易。

So I myself started to use crutches below which helped me a lot to find out what object to use for what data, and basically to imagine real world usage.

所以我自己开始使用下面的拐杖,它帮助我找出什么对象用于什么数据,并基本上想象现实世界的用法。

Though I not giving exact answers to the question the short text below might help reader who just started with R and is asking simmilar questions.

虽然我没有给出问题的确切答案,但下面的简短文本可能会帮助刚开始使用 R 并提出类似问题的读者。

  • Atomic vector ... I called that "sequence" for myself, no direction, just sequence of same types. [subsets.
  • Vector ... sequence with one direction from 2D, [subsets.
  • Matrix ... bunch of vectors with same length forming rows or columns, [subsets by rows and columns, or by sequence.
  • Arrays ... layered matrices forming 3D
  • Dataframe ... a 2D table like in excel, where I can sort, add or remove rows or columns or make arit. operations with them, only after some time I truly recognized that dataframe is an clever implementation of listwhere I can subset using [by rows and columns, but even using [[.
  • List ... to help myself I thought about list as of tree structurewhere [i]selects and returns whole branches and [[i]]returns item from the branch. And because it it is tree like structure, you can even use an index sequenceto address every single leaf on a very complex listusing its [[index_vector]]. Lists can be simple or very complex and can mix together various types of objects into one.
  • 原子向量……我自己称其为“序列”,没有方向,只是相同类型的序列。[子集。
  • 向量 ... 来自 2D 的一个方向的序列,[子集。
  • 矩阵 ... 一组长度相同的向量,形成行或列,[按行和列或按序列组成子集。
  • 数组 ... 形成 3D 的分层矩阵
  • 数据框……一个像excel一样的二维表,我可以在其中对行或列进行排序、添加或删除或制作。与他们一起操作,只是过了一段时间我才真正认识到数据帧是一个聪明的实现list,我可以在其中[按行和列使用子集,但即使使用[[.
  • 列表...帮助我自己,我想过列表作为tree structure其中[i]选择并返回整个树枝和[[i]]返回从分支项目。而且因为它是tree like structure,你甚至可以使用index sequence,以解决一个非常复杂的每一个叶list利用其[[index_vector]]。列表可以是简单的也可以是非常复杂的,并且可以将各种类型的对象混合在一起。

So for listsyou can end up with more ways how to select a leafdepending on situation like in following example.

因此,lists您最终可以通过更多方式leaf根据情况选择如何选择,如下例所示。

l <- list("aaa",5,list(1:3),LETTERS[1:4],matrix(1:9,3,3))
l[[c(5,4)]] # selects 4 from matrix using [[index_vector]] in list
l[[5]][4] # selects 4 from matrix using sequential index in matrix
l[[5]][1,2] # selects 4 from matrix using row and column in matrix

This way of thinking helped me a lot.

这种思维方式对我帮助很大。

回答by isomorphismes

Regarding vectors and the hash/array concept from other languages:

关于来自其他语言的向量和散列/数组概念:

  1. Vectors are the atoms of R. Eg, rpois(1e4,5)(5 random numbers), numeric(55)(length-55 zero vector over doubles), and character(12)(12 empty strings), are all "basic".

  2. Either lists or vectors can have names.

    > n = numeric(10)
    > n
     [1] 0 0 0 0 0 0 0 0 0 0
    > names(n)
    NULL
    > names(n) = LETTERS[1:10]
    > n
    A B C D E F G H I J 
    0 0 0 0 0 0 0 0 0 0
    
  3. Vectors require everything to be the same data type. Watch this:

    > i = integer(5)
    > v = c(n,i)
    > v
    A B C D E F G H I J           
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    > class(v)
    [1] "numeric"
    > i = complex(5)
    > v = c(n,i)
    > class(v)
    [1] "complex"
    > v
       A    B    C    D    E    F    G    H    I    J                          
    0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i
    
  4. Lists can contain varying data types, as seen in other answers and the OP's question itself.

  1. 向量是 R 的原子。例如,rpois(1e4,5)(5 个随机数)、numeric(55)(长度为 55 的零向量加倍)和character(12)(12 个空字符串)都是“基本的”。

  2. 列表或向量都可以有names.

    > n = numeric(10)
    > n
     [1] 0 0 0 0 0 0 0 0 0 0
    > names(n)
    NULL
    > names(n) = LETTERS[1:10]
    > n
    A B C D E F G H I J 
    0 0 0 0 0 0 0 0 0 0
    
  3. 向量要求所有内容都具有相同的数据类型。看这个:

    > i = integer(5)
    > v = c(n,i)
    > v
    A B C D E F G H I J           
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    > class(v)
    [1] "numeric"
    > i = complex(5)
    > v = c(n,i)
    > class(v)
    [1] "complex"
    > v
       A    B    C    D    E    F    G    H    I    J                          
    0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i 0+0i
    
  4. 列表可以包含不同的数据类型,如其他答案和 OP 的问题本身所示。

I've seen languages (ruby, javascript) in which "arrays" may contain variable datatypes, but for example in C++ "arrays" must be all the same datatype. I believe this is a speed/efficiency thing: if you have a numeric(1e6)you know its size and the location of every element a priori; if the thing might contain "Flying Purple People Eaters"in some unknown slice, then you have to actually parse stuff to know basic facts about it.

我见过“数组”可能包含可变数据类型的语言(ruby、javascript),但例如在 C++ 中,“数组”必须是相同的数据类型。我相信这是一个速度/效率的事情:如果你有一个numeric(1e6)你知道它的大小和每个元素的位置先验; 如果事物可能包含"Flying Purple People Eaters"在某个未知切片中,那么您必须实际解析事物以了解有关它的基本事实。

Certain standard R operations also make more sense when the type is guaranteed. For example cumsum(1:9)makes sense whereas cumsum(list(1,2,3,4,5,'a',6,7,8,9))does not, without the type being guaranteed to be double.

当类型得到保证时,某些标准 R 操作也更有意义。例如cumsum(1:9)有意义而cumsum(list(1,2,3,4,5,'a',6,7,8,9))没有,没有保证类型是双精度。



As to your second question:

至于你的第二个问题:

Lists can be returned from functions even though you never passed in a List when you called the function

即使在调用函数时从未传入列表,也可以从函数返回列表

Functions return different data types than they're input all the time. plotreturns a plot even though it doesn't take a plot as an input. Argreturns a numericeven though it accepted a complex. Etc.

函数始终返回与输入不同的数据类型。plot即使它不将绘图作为输入,也返回一个绘图。即使它接受 a 也Arg返回numerica complex。等等。

(And as for strsplit: the source code is here.)

(至于strsplit:源代码在这里。)