2015-01-25 4 views
2

У меня есть список фреймов данных например:Преобразование списка кадров данных в таблице данных

listOfDataFrames <- vector("list", 10) 

for (i in 1:10) { 
    listOfDataFrames[[i]] <- data.frame(a=rnorm(50), b=rnorm(50)) 
} 

Я хочу сделать одну таблицу данных с 3-мя столбцами (а, б, в), где а и Ь являются столбцами вышеперечисленных кадров данных, а c - индекс кадра данных в listOfDataframes.

ответ

4

Я бы просто сделать что-то вроде следующего:

library(data.table) 
Lens <- vapply(listOfDataframes, nrow, 1L) 
rbindlist(listOfDataframes)[, c := rep(seq_along(Lens), times = Lens)][] 
#    a   b c 
# 1: -1.6462894 1.0232899 1 
# 2: -0.5145108 -0.2134384 1 
# 3: -0.1171853 2.5456709 1 
# 4: 0.2735289 1.1948928 1 
# 5: 0.5739892 0.3939964 1 
# ---       
# 496: 0.9539835 -1.4100199 10 
# 497: -0.8697604 0.6793800 10 
# 498: 0.8601795 -0.3015890 10 
# 499: 0.8306091 -2.2269960 10 
# 500: -1.3407596 0.5014448 10 

В принципе, «Объектив» только цифры, сколько строк есть в каждом элементе списка (в данном случае, 50 в каждом), а затем просто используйте rep для вычисления значения для столбца «c». Поскольку результат rbindlist равен data.table, вы можете просто использовать :=, чтобы присвоить значение «c» в составной инструкции.


С development version теперь вы можете заменить vapply часть с новым idcol аргументом. idcol всегда персонаж type.

rbindlist(listOfDataframes, idcol = "c") 
+0

Отличный ответ. Какова цель 1L в vapply? – codeln

+1

@codeln, когда вы используете 'vapply' (в отличие от, например,' sapply'), вам нужно предоставить «шаблон», который определяет ожидаемый формат вывода. В этом случае вывод для 'nrow' является единственным целым числом, поэтому мы укажем его как« 1L ». – A5C1D2H2I1M1N2O1R2T1

+0

Вы также можете просто сделать это в одной строке, например 'rbindlist (Map (cbind, listOfDataframes, c = seq_len (length (listOfDataframes))))' хотя и не уверен в эффективности. –

3

Не хочу портить data.table партии, но с tidyr это будет один лайнер, если вы получите в индексе столбца, который затем можно удалить дополнительный X (если вы хотите), используя в качестве gsub следующим образом:

library(tidyr) 
library(data.table) 
setDT(unnest(listOfDataframes, "c"))[, c := gsub("X", "", c)][] 
#  c   a   b 
# 1: 1 0.3852528 -0.6886418 
# 2: 1 -2.3344659 -1.6770465 
# 3: 1 -0.8241178 -0.1445429 
# 4: 1 -1.5560673 -1.4205030 
# 5: 1 0.5981992 0.3564583 
# ---       
# 496: 10 0.1460643 1.1055989 
# 497: 10 0.3094036 -0.4239363 
# 498: 10 0.7756495 0.7656453 
# 499: 10 1.0037946 -0.2417804 
# 500: 10 -0.1241405 3.2421323 

вы также можете изменить порядок столбцов по ссылке, если вы хотите (если вы сохранили этот объект позволяет говорить в Res), используя функцию setcolorder

setcolorder(Res, c(2, 3, 1)) 
+1

Как это работает? '? unsest' говорит' col' - имя столбца, который должен быть неактивен. Но '' c "' не существует. – Arun

Смежные вопросы