R القائمة لإطار البيانات




list dataframe (10)

test1 <- list (c (a = 'a'، b = 'b'، c = 'c')، c (a = 'd'، b = 'e'، c = 'f')) as.data .frame (test1) abc 1 abc 2 def

test2 <- list (c ('a'، 'b'، 'c')، c (a = 'd'، b = 'e'، c = 'f'))

as.data.frame (test2) abc 1 abc 2 def

test3 <- list ('Row1' = c (a = 'a'، b = 'b'، c = 'c')، 'Row2' = c (a = 'd'، var2 = 'e'، var3 = 'F'))

as.data.frame (test3) abc var2 var3 Row1 abc
الصف 2

لدي قائمة متداخلة من البيانات. طوله 132 وكل عنصر قائمة طوله 20. هل هناك طريقة سريعة لتحويل هذا الهيكل إلى إطار بيانات يحتوي على 132 صف و 20 عمود بيانات؟

أنا جديد على R ، لذلك أعتقد أن هناك طريقة سهلة للقيام بذلك. لقد بحثت هنا عن Stack Overflow ولم أتمكن من العثور على سؤال مماثل ، لذا أعتذر إذا فاتني ذلك. بعض عينات البيانات:

l <- replicate(
  132,
  list(sample(letters, 20)),
  simplify = FALSE
)

Reshape2 ينتج نفس الإخراج كمثال plyr أعلاه:

library(reshape2)
l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
          , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
          , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
          , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
)
l <- melt(l)
dcast(l, L1 ~ L2)

عائدات:

  L1 var.1 var.2 var.3
1  a     1     2     3
2  b     4     5     6
3  c     7     8     9
4  d    10    11    12

إذا كنت تقريبًا خارج بكسل ، فيمكنك القيام بكل ذلك في خط واحد مع إعادة الصياغة ().


بافتراض أن قائمة قوائمك تسمى l :

df <- data.frame(matrix(unlist(l), nrow=132, byrow=T))

سيؤدي ما سبق إلى تحويل جميع أعمدة الأحرف إلى عوامل ، لتجنب حدوث ذلك ، يمكنك إضافة معلمة إلى استدعاء data.frame ():

df <- data.frame(matrix(unlist(l), nrow=132, byrow=T),stringsAsFactors=FALSE)

توسيع الإجابة على @ Marek: إذا كنت ترغب في تجنب تحول السلاسل إلى عوامل والكفاءة ليست محاولة مثيرة للقلق

do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))

للحالة العامة للقوائم المتداخلة بشكل عميق مع 3 مستويات أو أكثر مثل تلك التي تم الحصول عليها من JSON المتداخلة:

{
"2015": {
  "spain": {"population": 43, "GNP": 9},
  "sweden": {"population": 7, "GNP": 6}},
"2016": {
  "spain": {"population": 45, "GNP": 10},
  "sweden": {"population": 9, "GNP": 8}}
}

النظر في نهج melt() لتحويل القائمة المتداخلة إلى تنسيق طويل أولاً:

myjson <- jsonlite:fromJSON(file("test.json"))
tall <- reshape2::melt(myjson)[, c("L1", "L2", "L3", "value")]
    L1     L2         L3 value
1 2015  spain population    43
2 2015  spain        GNP     9
3 2015 sweden population     7
4 2015 sweden        GNP     6
5 2016  spain population    45
6 2016  spain        GNP    10
7 2016 sweden population     9
8 2016 sweden        GNP     8

متبوعًا بـ dcast() ثم إلى نطاق واسع مرة أخرى في مجموعة بيانات مرتبة حيث يشكل كل متغير عمودًا ، ويشكل كل رصد صفًا:

wide <- reshape2::dcast(tall, L1+L2~L3) 
# left side of the formula defines the rows/observations and the 
# right side defines the variables/measurements
    L1     L2 GNP population
1 2015  spain   9         43
2 2015 sweden   6          7
3 2016  spain  10         45
4 2016 sweden   8          9

مع rbind

do.call(rbind.data.frame, your_list)

تحرير: الإصدار السابق إرجاع data.frame من list بدلا من المتجهات (كما أشارIanSudbery في التعليقات).


هذا ما نجح في النهاية بالنسبة لي:

do.call("rbind", lapply(S1, as.data.frame))


يحتوي data.table الحزمة الدالة rbindlist وهو تطبيق do.call(rbind, list(...)) من do.call(rbind, list(...)) .

يمكن أن يأخذ قائمة lists أو data.tables أو data.tables كإدخال.

library(data.table)
ll <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
  , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
  , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
  , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
  )

DT <- rbindlist(ll)

هذا إرجاع data.table ترث. من data.frame .

إذا كنت تريد حقًا التحويل إلى استخدام as.data.frame(DT)


data.frame(t(sapply(mylistlist,c)))

يحول sapply إلى مصفوفة. يحول data.frame المصفوفة إلى إطار بيانات.


tibble الحزمة tibble على إطار enframe() يحل هذه المشكلة عن طريق إكراه كائنات list متداخلة على كائنات tibble ("هيكل" البيانات) المتداخلة المتداخلة. في ما يلي مثال موجز من R for Data Science :

x <- list(
    a = 1:5,
    b = 3:4, 
    c = 5:6
) 

df <- enframe(x)
df
#> # A tibble: 3 × 2
#>    name     value
#>   <chr>    <list>
#>    1     a <int [5]>
#>    2     b <int [2]>
#>    3     c <int [2]>

نظرًا لأن لديك العديد من الأعشاش في قائمتك ، l ، يمكنك استخدام unlist(recursive = FALSE) لإزالة التعشيش غير الضروري للحصول على قائمة تسلسلية واحدة فقط ثم تمريرها إلى enframe() . أستخدم tidyr::unnest() لإلغاء الإخراج في إطار بيانات "مرتبة" مستوى واحد ، والذي يحتوي على عمودين (أحدهما name المجموعة والآخر للملاحظات مع value المجموعات). إذا كنت تريد أن تكون الأعمدة واسعة ، يمكنك إضافة عمود باستخدام add_column() الذي يكرر فقط ترتيب القيم 132 مرة. ثم فقط spread() القيم.


library(tidyverse)

l <- replicate(
    132,
    list(sample(letters, 20)),
    simplify = FALSE
)

l_tib <- l %>% 
    unlist(recursive = FALSE) %>% 
    enframe() %>% 
    unnest()
l_tib
#> # A tibble: 2,640 x 2
#>     name value
#>    <int> <chr>
#> 1      1     d
#> 2      1     z
#> 3      1     l
#> 4      1     b
#> 5      1     i
#> 6      1     j
#> 7      1     g
#> 8      1     w
#> 9      1     r
#> 10     1     p
#> # ... with 2,630 more rows

l_tib_spread <- l_tib %>%
    add_column(index = rep(1:20, 132)) %>%
    spread(key = index, value = value)
l_tib_spread
#> # A tibble: 132 x 21
#>     name   `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`   `9`  `10`  `11`
#> *  <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1      1     d     z     l     b     i     j     g     w     r     p     y
#> 2      2     w     s     h     r     i     k     d     u     a     f     j
#> 3      3     r     v     q     s     m     u     j     p     f     a     i
#> 4      4     o     y     x     n     p     i     f     m     h     l     t
#> 5      5     p     w     v     d     k     a     l     r     j     q     n
#> 6      6     i     k     w     o     c     n     m     b     v     e     q
#> 7      7     c     d     m     i     u     o     e     z     v     g     p
#> 8      8     f     s     e     o     p     n     k     x     c     z     h
#> 9      9     d     g     o     h     x     i     c     y     t     f     j
#> 10    10     y     r     f     k     d     o     b     u     i     x     s
#> # ... with 122 more rows, and 9 more variables: `12` <chr>, `13` <chr>,
#> #   `14` <chr>, `15` <chr>, `16` <chr>, `17` <chr>, `18` <chr>,
#> #   `19` <chr>, `20` <chr>




dataframe