rbindlist список столбцов data.frames и выбор уникальных значений - PullRequest
0 голосов
/ 26 июня 2018

У меня есть data.table 'DT' со столбцом ('col2'), который представляет собой список фреймов данных:

require(data.table)
DT <- data.table(col1 = c('A','A','B'),
                 col2 = list(data.frame(colA = c(1,3,54, 23), 
                                        colB = c("aa", "bb", "cc", "hh")),
                             data.frame(colA =c(23, 1),
                                       colB = c("hh", "aa")), 
                             data.frame(colA = 1,
                                       colB = "aa")))

> DT
   col1         col2
1:    A <data.frame>
2:    A <data.frame>
3:    B <data.frame>

>> DT$col2
[[1]]
  colA colB
1    1   aa
2    3   bb
3   54   cc
4   23   hh

[[2]]
  colA colB
1   23   hh
2    1   aa

[[3]]
  colA colB
1    1   aa

Каждый data.frame в col2 имеет два столбца colA и colB.Я хотел бы иметь вывод data.table, который связывает каждую уникальную строку этих фреймов данных, основанную на col1 DT.Я думаю, это похоже на использование rbindlist в статистической функции data.table.

Это желаемый результат:

> #desired output
> output
   colA colB col1
1:    1   aa    A
2:    3   bb    A
3:   54   cc    A
4:   23   hh    A
5:    1   aa    B

Кадр данных второй строки DT (DT[2, col2]) имеет повторяющиеся записи, и для каждого уникального столбца требуются только уникальные записи.

Я попробовал следующее, и я получил ошибку.

desired_output <- DT[, lapply(col2, function(x) unique(rbindlist(x))), by = col1]
# Error in rbindlist(x) : 
#   Item 1 of list input is not a data.frame, data.table or list

Это «работает», хотя и не желательновывод:

unique(rbindlist(DT$col2))
   colA colB
1:    1   aa
2:    3   bb
3:   54   cc
4:   23   hh

В любом случае можно использовать rbindlist в статистической функции data.table?

Ответы [ 4 ]

0 голосов
/ 26 июня 2018

желательны только уникальные записи для каждого уникального col1

Если вы добавите столбец для col1, приведенное выше выражение означает «уникальные записи» (безусловное для столбцов).

Ответ Хенрика - один из способов сохранить col1.Другое:

unique(DT[, rbindlist(setNames(col2, col1), id="col1")])

Полагаю, это должно быть более эффективным, чем

bycols = "col1"
unique(DT[, rbindlist(col2), by=bycols])   # Henrik's

, хотя расширение либо (1) col1 не является символьным столбцом (следовательно, подходит для setNames) или (2) наличие нескольких столбцов by= не так очевидно.В любом из этих случаев я бы сделал столбец .id равным номерам строк DT, а затем скопировал бы их:

bycols = "col1"
res = unique(DT[, rbindlist(col2, id="DT_row")])
res[, (bycols) := DT[DT_row, ..bycols]]

Чтобы поместить эти столбцы в первую / левую позицию, я думаю, что setcolorder(res, bycols) долженработаю, но я слишком старая версия data.table, чтобы увидеть это.

Также есть открытый выпуск для tidyr::unnest -подобной функции.

0 голосов
/ 26 июня 2018

Это работает:

DT1<-apply(DT, 1, function(x){cbind(col1=x$col1,x$col2)})
unique(rbindlist(DT1))
#   col1 colA colB
#1:    A    1   aa
#2:    A    3   bb
#3:    A   54   cc
#4:    A   23   hh
#5:    B    1   aa
0 голосов
/ 26 июня 2018

Группа by 'col1', запуск rbindlist на 'col2':

unique(DT[ , rbindlist(col2), by = col1]) # trimmed thanks to @snoram
#    col1 colA colB
# 1:    A    1   aa
# 2:    A    3   bb
# 3:    A   54   cc
# 4:    A   23   hh
# 5:    B    1   aa
0 голосов
/ 26 июня 2018

Вы можете сделать что-то хакерское, как это:

nDT <- cbind(rbindlist(DT[[2]]), col1 = rep(DT[[1]], sapply(DT[[2]], nrow)))
nDT[!duplicated(nDT)]
   colA colB col1
1:    1   aa    A
2:    3   bb    A
3:   54   cc    A
4:   23   hh    A
5:    1   aa    B

Или использовать тидир (Вдохновленный комментарием PKumar):

unique(tidyr::unnest(DT))

Или более обобщенную базу R:

names(DT[[2]]) <- DT[[1]]
ndf <- do.call(rbind, DT[[2]])
ndf$col1 <- substr(row.names(ndf), 1, 1)
unique(ndf)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...