2012-11-03 161 views
2

我被R动态创建列表的方式困扰,我希望有人能够帮助我理解正在发生的事情以及如何解决我的代码。我的问题是,对于长度为1的矢量的赋值,指定了一个已命名的矢量,但是赋值长度大于1的矢量的赋值将被分配一个列表。我希望的结果是,无论我分配的向量的长度如何,都会分配一个列表。我如何获得这样的结果?动态列表创建

例如,

types <- c("a", "b") 
lst <- vector("list", length(types)) 
names(lst) <- types 
str(lst) 
List of 2 
$ a: NULL 
$ b: NULL 
lst$a[["foo"]] <- "hi" 
lst$b[["foo"]] <- c("hi", "SO") 
str(lst) 
List of 2 
$ a: Named chr "hi" 
    ..- attr(*, "names")= chr "foo" 
$ b:List of 1 
    ..$ foo: chr [1:2] "hi" "SO" 
str(lst$a) 
Named chr "hi" 
- attr(*, "names")= chr "foo" 
str(lst$b) 
List of 1 
$ foo: chr [1:2] "hi" "SO" 

我想有作为的结果是一种数据结构,看起来像这样。

List of 2 
$ a:List of 1 
    ..$ foo: chr [1] "hi" 
$ b:List of 1 
    ..$ foo: chr [1:2] "hi" "SO" 

回答

3

虽然我也觉得奇怪,它记录在?[[

递归(列表等)对象:

[...] 

When ‘$<-’ is applied to a ‘NULL’ ‘x’, it first coerces ‘x’ to 
‘list()’. This is what also happens with ‘[[<-’ if the 
replacement value ‘value’ is of length greater than one: if 
‘value’ has length 1 or 0, ‘x’ is first coerced to a zero-length 
vector of the type of ‘value’. 

要覆盖的行为,你可以专门创建空列表之前动态地分配给他们:

lst$a <- list() 
lst$b <- list() 

或类似乔什以下建议,更换您的lst <- vector("list", length(types))lst <- replicate(length(types), list())

现在‘x’lst$alst$b)不是‘NULL’但一个空的列表,如你预期的代码应工作:

lst$a[["foo"]] <- "hi" 
lst$b[["foo"]] <- c("hi", "SO") 
str(lst) 
# List of 2 
# $ a:List of 1 
# ..$ foo: chr "hi" 
# $ b:List of 1 
# ..$ foo: chr [1:2] "hi" "SO" 
+1

+1好主意。 'lst < - replicate(length(types),list())'会更干净。 –

+0

或者只是在'list' – hadley

+0

@hadley包装作业的右侧,这是我的初步猜测,但它不是做同样的事情:它是'lst $ a',需要是一个列表,而不是'lst美元[ “富”]]'。 – flodel

2

我想你只需要创建你想要的类型,并将它们分配:

R> qq <- list(a=list(foo="Hi"), b=list(foo=c("Hi", "SO"))) 
R> qq 
$a 
$a$foo 
[1] "Hi" 


$b 
$b$foo 
[1] "Hi" "SO" 


R> 

您所有的要求都满足:

R> class(qq) 
[1] "list" 
R> names(qq) 
[1] "a" "b" 
R> sapply(qq, names) 
    a  b 
"foo" "foo" 
R>