2015-07-21 5 views
4

У меня есть dataframe в следующем формате:Unlisting колонны по группам

id | name    | logs         
---+--------------------+----------------------------------------- 
84 |   "zibaroo" |        "C47931038" 
12 | "fabien kelyarsky" | c("C47331040", "B19412225", "B18511449") 
96 |  "mitra lutsko" |    c("F19712226", "A18311450") 
34 |  "PaulSandoz" |        "A47431044" 
65 |  "BeamVision" |        "D47531045" 

Как вы видите столбец «логи» включает в себя векторы строк в каждой ячейке.

Есть ли эффективный способ преобразования кадра данных в длинный формат (по одному наблюдению за строку) без промежуточного этапа разделения «журналов» на несколько столбцов?

Это важно, потому что набор данных очень велик, и количество журналов на человека кажется произвольным.

Другими словами, мне нужно следующее:

id | name    | log         
---+--------------------+------------ 
84 |   "zibaroo" | "C47931038" 
12 | "fabien kelyarsky" | "C47331040" 
12 | "fabien kelyarsky" | "B19412225" 
12 | "fabien kelyarsky" | "B18511449" 
96 |  "mitra lutsko" | "F19712226" 
96 |  "mitra lutsko" | "A18311450" 
34 |  "PaulSandoz" | "A47431044" 
65 |  "BeamVision" | "D47531045" 

Вот dput секции реального dataframe:

structure(list(id = 148:157, name = c("avihil1", "Niarfe", "doug henderson", 
"nick tan", "madisp", "woodbusy", "kevinhcross", "cylol", "andrewarrow", 
"gstavrev"), logs = list("Z47331572", "Z47031573", c("F47531574", 
"B195945", "D186871", "S192939", "S182865", "G19539045"), c("A47231575", 
"A190933", "C181859"), "F47431576", c("B47231577", "D193936", 
"Q184862"), "Y47331579", c("A47531580", "Z195944", "B185870"), 
"N47731581", "E47231582")), .Names = c("id", "name", "logs" 
), row.names = 149:158, class = "data.frame") 
+0

Просьба 'dput' из (кусочек) ваших данных. – SabDeM

+1

На самом деле, как выглядит текстовый файл или что вы воображаете, что может содержать объект R-data? Если последнее, то вместо этого вы должны вывести вывод 'dput (object)'. –

+1

вам, вероятно, нужна библиотека (splitstackshape); cSplit (data, 'log', ',', direction = 'long') ' –

ответ

5

Это идеальный случай для tidyr:

library(tidyr) 
library(dplyr) 
dat %>% unnest(logs) 
+0

. Проблема здесь (и я это заметил), что некоторые члены не имеют журналов (переменная logs имеет значение null или пустой вектор/список). Unnest подавляет эти записи и, похоже, не предлагает какой-либо опции для переопределения этого поведения по умолчанию. Любое предложение? – retrography

+1

Вы можете попробовать сменить их на NA first - dat $ logs [sapply (dat $ logs, length) == 0] <- NA, вызов unsest. – jeremycg

+0

Я всегда забываю, что NA и NULL - это два разных зверя в привычках, связанных с базой данных R. Bad. Благодарю. Прекрасно работает. – retrography

8

Использование listCol_l от splitstackshape может быть хорошим вариантом здесь, поскольку колонка «журналы» в data.frame является list

library(splitstackshape) 
listCol_l(df, 'logs') 

# id   name logs_ul 
#1: 148  avihil1 Z47331572 
#2: 149   Niarfe Z47031573 
#3: 150 doug henderson F47531574 
#4: 150 doug henderson B195945 
#5: 150 doug henderson D186871 
#6: 150 doug henderson S192939 
#7: 150 doug henderson S182865 
#8: 150 doug henderson G19539045 
#9: 151  nick tan A47231575 
#10: 151  nick tan A190933 
#11: 151  nick tan C181859 
#12: 152   madisp F47431576 
#13: 153  woodbusy B47231577 
#14: 153  woodbusy D193936 
#15: 153  woodbusy Q184862 
#16: 154 kevinhcross Y47331579 
#17: 155   cylol A47531580 
#18: 155   cylol Z195944 
#19: 155   cylol B185870 
#20: 156 andrewarrow N47731581 
#21: 157  gstavrev E47231582 
+0

Вы посмотрели на 'dput'? 'logs' - это список –

+2

Nice. Я всегда забываю об этой функции. –

5

Просто, чтобы показать другой вариант

library(data.table) 
setDT(df)[, .(logs = unlist(logs)), by = .(id, name)] 
Смежные вопросы