我想用列表填充数据框的一列。根据示例代码,我发现了here:
d <- data.frame(id=1:2, name=c("Jon", "Mark"))
d
d$children <- list(list("Mary", "James"), list("Greta", "Sally"))
d
我希望以下代码可以工作:
d <- data.frame(id=1:2, name=c("Jon", "Mark"))
d
d["children"] <- list(list("Mary", "James"), list("Greta", "Sally"))
d
但是它给出了错误:
Warning message:
In `[<-.data.frame`(`*tmp*`, "children", value = list(list("Mary", :
provided 2 variables to replace 1 variables
基于阅读this post和this answer的代码,我将其更改为:
d <- data.frame(id=1:2, name=c("Jon", "Mark"))
d
d["children"] <- list(list(list("Mary", "James"), list("Greta", "Sally")))
d
效果很好。问题是,这是怎么回事?对list
的额外调用完成了什么?谢谢
答案 0 :(得分:1)
这里发生了几件事。当使用单括号[ ]
或双括号[[ ]]
进行索引时,R会产生不同的行为。简而言之,当使用单括号将数据帧索引时,R期望(或返回)列表对象。使用双括号时,将返回基础的 vector 。
请注意,下面的第一个示例带有单括号,保留了数据框列的结构和命名,而双括号示例则将列的原始内容作为矢量返回。
> str(mtcars['mpg'])
'data.frame': 32 obs. of 1 variable:
$ mpg: num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
> str(mtcars[['mpg']])
num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
要回答您的问题,为什么对list()
的多余调用完全有帮助,str
可以使您对此有所了解:
您的原始代码(不含多余的list()
)是长度2的列表:
> str(list(list("Mary", "James"), list("Greta", "Sally")))
List of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
此操作失败,因为d['children']
希望与长度为1的对象匹配。但是,添加额外的list()
会创建一个长度为1的“外部”列表,因此分配成功。 >
str(list(list(list("Mary", "James"), list("Greta", "Sally"))))
List of 1
$ :List of 2
..$ :List of 2
.. ..$ : chr "Mary"
.. ..$ : chr "James"
..$ :List of 2
.. ..$ : chr "Greta"
.. ..$ : chr "Sally"
最后,如果您使用双括号索引,您的原始代码(无需使用额外的list()
)就可以使用:
d[["children"]] <- list(list("Mary", "James"), list("Greta", "Sally"))
答案 1 :(得分:0)
@jdobres的答案使我开始研究以下示例,这有助于我理解(有点)发生了什么。
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> d
id name
1 1 Jon
2 2 Mark
> add <- list(list("Mary", "James"), list("Greta", "Sally"))
> d$children <- add
> d
id name children
1 1 Jon Mary, James
2 2 Mark Greta, Sally
> str(d$children)
List of 2 # d$children is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
> str(add)
List of 2 # add is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
之所以可行,是因为d$children <- add
的lhs和rhs都是具有2个项目的列表。
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> d
id name
1 1 Jon
2 2 Mark
> add <- list(list("Mary", "James"), list("Greta", "Sally"))
> d["children"] <- add
Warning message:
In `[<-.data.frame`(`*tmp*`, "children", value = list(list("Mary", :
provided 2 variables to replace 1 variables
> d
id name children
1 1 Jon Mary
2 2 Mark James
> str(d["children"])
'data.frame': 2 obs. of 1 variable: # d["children"] is 1 var. with 2 obs.
$ children:List of 2
..$ : chr "Mary"
..$ : chr "James"
> str(add)
List of 2 # add is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
这不起作用,因为d$children <- add
的lhs是“ 1 var。with 2 obs”。但是rhs是“一个2的列表”。
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> add <- list(list(list("Mary", "James"), list("Greta", "Sally")))
> d["children"] <- add
> d
id name children
1 1 Jon Mary, James
2 2 Mark Greta, Sally
> str(d["children"])
'data.frame': 2 obs. of 1 variable: # d["children"] is 1 var. with 2 obs.
$ children:List of 2
..$ :List of 2
.. ..$ : chr "Mary"
.. ..$ : chr "James"
..$ :List of 2
.. ..$ : chr "Greta"
.. ..$ : chr "Sally"
> str(add)
List of 1 # add is 1 list with 2 lists
$ :List of 2
..$ :List of 2
.. ..$ : chr "Mary"
.. ..$ : chr "James"
..$ :List of 2
.. ..$ : chr "Greta"
.. ..$ : chr "Sally"
这里的命名有点不合逻辑,但是如果您接受一个列表必须在列表中才能计为列表,则上述方法有效,因为d$children <- add
的lhs是“ 1 var。with 2肥胖。”而rhs是“ 1个列表2个列表”。注意对称性1var:2lists :: 1list:2lists。
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> d
id name
1 1 Jon
2 2 Mark
> add <- list(list("Mary", "James"), list("Greta", "Sally"))
> d[["children"]] <- add
> d
id name children
1 1 Jon Mary, James
2 2 Mark Greta, Sally
> str(d[["children"]])
List of 2 # d[["children"]] is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
> str(add)
List of 2 # add is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
像第一个示例一样,之所以有用,是因为d$children <- add
的lhs和rhs都是具有2个项目的列表。
我仍然不确定在add
评估为str(add)
的情况下应该调用List of 2...
的封闭结构,但这可能并不重要。