首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用R中的列表填充数据帧

用R中的列表填充数据帧
EN

Stack Overflow用户
提问于 2019-06-07 22:50:22
回答 2查看 7.6K关注 0票数 2

我想用列表填充数据帧的一列。基于我找到的示例代码这里

代码语言:javascript
复制
d <- data.frame(id=1:2, name=c("Jon", "Mark"))
d
d$children <-  list(list("Mary", "James"), list("Greta", "Sally"))
d

我期望以下代码能够工作:

代码语言:javascript
复制
d <- data.frame(id=1:2, name=c("Jon", "Mark"))
d
d["children"] <-  list(list("Mary", "James"), list("Greta", "Sally"))
d

但它给出了一个错误:

代码语言:javascript
复制
Warning message:
In `[<-.data.frame`(`*tmp*`, "children", value = list(list("Mary",  :
  provided 2 variables to replace 1 variables

基于读取这个职位这个答案,我将代码更改为:

代码语言:javascript
复制
d <- data.frame(id=1:2, name=c("Jon", "Mark"))
d
d["children"] <-  list(list(list("Mary", "James"), list("Greta", "Sally")))
d

效果很好。问题是,这是怎么回事?对list的额外调用实现了什么?谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-07 23:40:14

这里发生了几件事。当使用单括号[ ]或双括号[[ ]]进行索引时,r会产生不同的行为。简而言之,当使用单括号对数据帧进行索引时,R期望(或返回) list对象。使用双括号时,将返回基础向量.

请注意,下面的第一个示例(带有单括号)保留数据帧列的结构和命名,而双括号示例将列的原始内容作为向量返回。

代码语言:javascript
复制
> 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的列表:

代码语言:javascript
复制
> 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的“外部”列表,因此赋值成功。

代码语言:javascript
复制
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())就可以工作了:

代码语言:javascript
复制
d[["children"]] <-  list(list("Mary", "James"), list("Greta", "Sally"))
票数 1
EN

Stack Overflow用户

发布于 2019-06-08 02:12:03

@jdobres的回答让我玩了下面的例子,这帮助我理解了到底发生了什么。

代码语言:javascript
复制
> 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都是有两个项目的列表。

代码语言:javascript
复制
> 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变种,有2枚。“但rhs是“2人名单”。

代码语言:javascript
复制
> 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.with2obs“。而rhs是"1份名单和2份名单“。注意对称的1var:2 1list::1 1list:2 1list。

代码语言:javascript
复制
> 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都是包含两个项的列表。

add的计算结果为List of 2...的情况下,我仍然不确定应该调用List of 2...的封闭结构,但这可能并不重要。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56501985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档