Erstellen Sie einen data.frame, in dem eine Spalte eine Liste ist


80

Ich weiß, wie man eine Listenspalte hinzufügt:

> 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

Das funktioniert, aber nicht:

> 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

Warum?

Gibt es auch eine Möglichkeit, df(oben) in einem einzigen Aufruf von zu erstellen data.frame?

Antworten:


103

Etwas dunkel, von ?data.frame:

Wenn eine Liste, ein Datenrahmen oder eine Matrix an 'data.frame' übergeben wird, ist es so, als ob jede Komponente oder Spalte als separates Argument übergeben worden wäre (mit Ausnahme der Matrizen der Klasse "model.matrix" und der durch "I " geschützten ' ).

(Betonung hinzugefügt).

Damit

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

scheint zu funktionieren.


17
Für Interessierte bedeutet "I" "Interperetation / Konvertierung von Objekten verhindern". Es wird ein identisches Objekt erstellt, wobei jedoch "AsIs" an die Klassen angehängt werden. Die Klasse "AsIs" ist wirklich nur dazu da, von den Funktionen data.frame () und formula () gelesen zu werden. Erfahren Sie hier mehr .
Pwilcox

2
super, danke für die lösung. obwohl nur Ifür Inhibit Interperetation / Conversion von Objekten scheint ein bisschen zu kurz :)
sertsedat

@pwilcox sehr interessant. Gibt es eine Methode, um ein Objekt aufzurufen, um zu verstehen, ob es von mir geschützt wird? Ich denke es ist class()? zB I(iris) -> i; i %>% class() 3 [1] "AsIs" "data.frame"(gibt die AsIs-Klasse zurück)
stevec

33

Wenn Sie mit arbeiten data.tables, können Sie den Anruf bei vermeidenI()

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

Dies ist ein unterschätztes Merkmal data.tablemit großem Abstand
Daten Prinzessin

22

data_frames (verschiedentlich genannt tibbles, tbl_df, tbl) nativ die Erstellung von Listenspalten mit der Unterstützung data_frameKonstruktor. Für sie Last einen der vielen Bibliotheken mit ihnen zu verwenden wie tibble, dplyroder 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]>

Sie sind eigentlich data.framesunter der Haube, aber etwas modifiziert. Sie können fast immer wie gewohnt verwendet werden data.frames. Die einzige Ausnahme, die ich gefunden habe, ist, dass Leute, die unangemessene Klassenprüfungen durchführen, Probleme verursachen:

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

Ich empfehle, darüber in R 4 Data Science (kostenlos) zu lesen .


1
R bewegt sich und wächst und ich denke, dies ist die Antwort von 2018 auf die Frage und sollte irgendwie als solche gekennzeichnet werden.
Fitzroy Hogsflesh

Wenn es populär genug ist, wird es nach oben steigen. Viele von uns benutzen immer noch Base R ...
Ben Bolker
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.