Как преобразовать R dataframe в список списков? - PullRequest
2 голосов
/ 16 апреля 2020

У меня есть фрейм данных с 3 столбцами ID, категория, item_id. Я хочу сгруппировать по идентификатору, категории и item_id в векторе

df <- data.table(ID=c(1,1,1,2,2,2),
              category=c("A", "A", "B", "B", "B", "A"),
              item_id=c("1a", "2a", "1b","2b", "2b", "2a" ))
  > df
      ID category item_id
   1:  1        A      1a
   2:  1        A      2a
   3:  1        B      1b
   4:  2        B      2b
   5:  2        B      2b
   6:  2        A      2a

Я хочу преобразовать указанный выше фрейм данных в список со списком item_id в качестве вектора. Я хочу указанную выше таблицу в приведенном ниже формате списка.

df2 <- list("1"=list("A"=c("1a", "2a"), "B"=c("2b")),
            "2"=list("A"=c("2a"), "B"=c("2b" ,"2b")))
>     df2
   $`1`
   $`1`$A
  [1] "1a" "2a"

   $`1`$B
  [1] "2b"

   $`2`
  $`2`$A
  [1] "2a"

  $`2`$B
  [1] "2b" "2b"

Я хочу применить эту операцию к миллиону строк, пожалуйста, предложите эффективное решение

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Простой способ - определить пользовательскую функцию nest, которая рекурсивно работает для создания вложенного списка

nest <- function(x) {
  if (length(x)==2) return(split(x[,-1],x[,1]))
  lapply(split(x[-1],x[1]), nest)
}

таким, что

> nest(df)
$`1`
$`1`$A
[1] 1a 2a
Levels: 1a 1b 2a 2b

$`1`$B
[1] 1b
Levels: 1a 1b 2a 2b


$`2`
$`2`$A
[1] 2a
Levels: 1a 1b 2a 2b

$`2`$B
[1] 2b 2b
Levels: 1a 1b 2a 2b
1 голос
/ 16 апреля 2020

Поскольку вам нужен вложенный список, мы можем использовать вложенный split:

lapply(split(df[, -1], df$ID), function(x) split(x$item_id, x$category))

#$`1`
#$`1`$A
#[1] "1a" "2a"

#$`1`$B
#[1] "1b"


#$`2`
#$`2`$A
#[1] "2a"

#$`2`$B
#[1] "2b" "2b"
...