Створіть data.frame, де стовпець є списком


80

Я знаю, як додати стовпець списку:

> 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

Це працює, але ні:

> 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

Чому?

Крім того, чи є спосіб створити df(вище) за один виклик data.frame?

Відповіді:


103

Трохи неясно, від ?data.frame:

Якщо список або фрейм даних або матриця передаються в 'data.frame', це ніби кожен компонент або стовпець передається як окремий аргумент (за винятком матриць класу '' model.matrix '' та тих, які захищені 'I ' ).

(курсив додано).

Так

data.frame(a=1:3,b=I(list(1,1:2,1:3)))

здається, працює.


17
Для зацікавлених "Я" означає "Заборонити взаємодію / перетворення об'єктів". Він створює ідентичний об'єкт, але "AsIs" додається до набору класів. Клас "AsIs" насправді просто для того, щоб його читали функції data.frame () та formula (). Дізнайтеся більше тут .
pwilcox

2
дивно, дякую за рішення. хоча тільки Iдля
заборони інтерперетації

@pwilcox дуже цікаво. Чи існує якийсь спосіб викликати об’єкт, щоб зрозуміти, чи захищений він I? Я думаю це class()? наприклад I(iris) -> i; i %>% class() 3 [1] "AsIs" "data.frame"(повертає клас AsIs)
stevec

33

Якщо ви працюєте з 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

Це недооцінена риса з data.tableвеликим відривом
дані принцеси

22

data_frames ( по- різному називають tibbles, tbl_df, tbl) спочатку підтримує створення стовпців списку з допомогою data_frameконструктора. Для їх використання завантажте одну з багатьох бібліотек, таких як tibble, dplyrабо tidyverse.

> 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]>

Вони насправді 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

Я рекомендую прочитати про них у R 4 Data Science (безкоштовно).


1
R рухається і зростає, і я думаю, що це відповідь 2018 року на питання, і якось його слід позначити як такий.
Фіцрой Хогсфлеш,

Якщо вона досить популярна, вона підніметься на вершину. Багато з нас все ще використовують базову R ...
Бен Болкер,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.