创建一个data.frame,其中列是列表

flo*_*del 69 r list dataframe

我知道如何添加列表列:

> df <- data.frame(a=1:3)
> df$b <- list(1:1, 1:2, 1:3)
> df
  a       b
1 1       1
2 2    1, 2
3 3 1, 2, 3
Run Code Online (Sandbox Code Playgroud)

这有效,但不是:

> df <- data.frame(a=1:3, b=list(1:1, 1:2, 1:3))
Error in data.frame(1L, 1:2, 1:3, check.names = FALSE, stringsAsFactors = TRUE) : 
  arguments imply differing number of rows: 1, 2, 3
Run Code Online (Sandbox Code Playgroud)

为什么?

另外,有没有办法df在一次调用中创建(上面)data.frame

Ben*_*ker 88

略显晦涩,来自?data.frame:

如果将列表或数据框或矩阵传递给'data.frame',就好像每个组件或列都已作为单独的参数传递(类''model.matrix''的矩阵和'I'保护的矩阵除外").

所以

data.frame(a=1:3,b=I(list(1,1:2,1:3)))
Run Code Online (Sandbox Code Playgroud)

似乎工作.

  • 对于那些感兴趣的人,"我"的意思是"禁止对象的交换/转换".它创建了一个相同的对象,但在类集合中附加了"AsIs"."AsIs"类实际上只是由data.frame()和formula()函数读取.了解更多[此处](https://stat.ethz.ch/R-manual/R-devel/library/base/html/AsIs.html). (11认同)
  • 太棒了,感谢您的解决方案。虽然只是用于禁止互译/对象转换的“I”似乎有点太短了:) (2认同)
  • @stevec参见[GKi最近的答案](/sf/answers/4835060471/),在我看来好多了。 (2认同)

mne*_*nel 32

如果您正在使用data.tables,那么您可以避免拨打电话I()

library(data.table)
# the following works as intended
data.table(a=1:3,b=list(1,1:2,1:3))

   a     b
1: 1     1
2: 2   1,2
3: 3 1,2,3
Run Code Online (Sandbox Code Playgroud)

  • 这是 ```data.table``` 的一个被低估的特性。 (3认同)

Del*_*eet 20

data_frameS(所谓的不同tibbles,tbl_df,tbl)原生支持使用列表的列的创建data_frame构造函数.要使用它们,请使用它们加载许多库中的一个,例如tibble,dplyrtidyverse.

> data_frame(abc = letters[1:3], lst = list(1:3, 1:3, 1:3))
# A tibble: 3 × 2
    abc       lst
  <chr>    <list>
1     a <int [3]>
2     b <int [3]>
3     c <int [3]>
Run Code Online (Sandbox Code Playgroud)

他们实际上是data.frames在引擎盖下,但有些修改.它们几乎总能正常使用data.frames.我发现的唯一例外是,当人们进行不适当的课堂检查时,会导致问题:

> #no problem
> data.frame(x = 1:3, y = 1:3) %>% class
[1] "data.frame"
> data.frame(x = 1:3, y = 1:3) %>% class == "data.frame"
[1] TRUE
> #uh oh
> data_frame(x = 1:3, y = 1:3) %>% class
[1] "tbl_df"     "tbl"        "data.frame"
> data_frame(x = 1:3, y = 1:3) %>% class == "data.frame"
[1] FALSE FALSE  TRUE
> #dont use if with improper testing!
> if(data_frame(x = 1:3, y = 1:3) %>% class == "data.frame") "something"
Warning message:
In if (data_frame(x = 1:3, y = 1:3) %>% class == "data.frame") "something" :
  the condition has length > 1 and only the first element will be used
> #proper
> data_frame(x = 1:3, y = 1:3) %>% inherits("data.frame")
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

我建议在R 4数据科学(免费)中阅读它们.

  • 如果它足够受欢迎,它就会上升到顶峰。我们很多人仍然使用基础 R ... (6认同)

GKi*_*GKi 6

您可以使用list2DF创建一个data.frame,其中列是list

x <- list2DF(list(a=1:3, b=list(1:1, 1:2, 1:3)))
#x <- data.frame(a=1:3, list2DF(list(b=list(1:1, 1:2, 1:3)))) #Alternative

x
#  a       b
#1 1       1
#2 2    1, 2
#3 3 1, 2, 3

str(x)
#'data.frame':   3 obs. of  2 variables:
# $ a: int  1 2 3
# $ b:List of 3
#  ..$ : int 1
#  ..$ : int  1 2
#  ..$ : int  1 2 3
Run Code Online (Sandbox Code Playgroud)

attr AsIs有了这个,你就没有了data.frame使用时会拥有的东西I