Как преобразовать список с элементом различной длины в информационный кадр - PullRequest
2 голосов
/ 24 сентября 2019

Здесь я так часто сталкиваюсь с такой проблемой, когда у меня есть петля.Первый решен.

[1] У меня есть такой список:

myList <- list(a = c(1, 2, 3), b = c(4, 5, 6, 7), c= c(9,10))

Теперь я хочу преобразовать список в data.frame следующим образом:

    Value
a   1, 2, 3
b   4, 5, 6, 7
c   9, 10

кто-нибудь покажет мне общую функцию по основному R?

[2] Возникла новая проблема:

mynewList <- list(a = c(1, 2, 3, "f"), b = c(4, 5, 6), c= c(9,10), d=list(1,2))

Я хочу преобразовать mynewlist в фрейм данных, подобный этому:

    a   b   c   d 
1   1   4   9  1
2   2   5  10  2
3   3   6  na  na
4   f   na na  na

Я использую приведенную ниже команду раньше, она работает без элемента d.но это не сработало.

df<-data.frame(lapply(myList, "length<-" , max(lengths(myList))))

Кто-нибудь показывает мне общую функцию по основному R?

Ответы [ 4 ]

2 голосов
/ 24 сентября 2019

1.Мы можем использовать sapply и paste:

df <- data.frame(Value = sapply(myList, paste, collapse = ','))

Выход:

    Value
a   1,2,3
b 4,5,6,7
c    9,10

2.Мы можем unlist каждый элемент списка до применения максимальной длины:

df <- data.frame(lapply(mynewList, function(x) {
  x <- unlist(x)
  length(x) <- max(lengths(mynewList))
  return(x)
}))

Вывод:

  a  b  c  d
1 1  4  9  1
2 2  5 10  2
3 3  6 NA NA
4 f NA NA NA
0 голосов
/ 24 сентября 2019

Это самое простое решение, которое я могу придумать, используя базу R.

cbindlist = function(list_obj){

  lengths = unlist(lapply(list_obj, length))
  NA_lengths = sapply(lengths, function(x) max(lengths) - x)
  cols = names(list_obj)

  out = data.frame(sapply(1:length(list_obj), function(x) c(list_obj[[x]], rep(NA, NA_lengths[x]))))
  colnames(out) = cols

  return(out)
}

Это работает для обоих ваших примеров:

lista = list(a = c(1, 2, 3), b = c(4, 5, 6, 7), c = c(9,10))
newlista = list(a = c(1, 2, 3, "f"), b = c(4, 5, 6), c= c(9,10), d=list(1,2))

> cbindlist(lista)
   a b  c
1  1 4  9
2  2 5 10
3  3 6 NA
4 NA 7 NA

> cbindlist(newlista)
  a  b  c  d
1 1  4  9  1
2 2  5 10  2
3 3  6 NA NA
4 f NA NA NA
0 голосов
/ 24 сентября 2019

Что касается обновленного запроса, у меня была похожая проблема, связанная со связыванием столбцов разной длины.Я решил написать обтекание cbind, которое также добавляет NA значения.

cbind.NA <- function (...) {
   myDFs <- list(...)
   myDFs <- lapply(myDFs, as.matrix)
   n <- max(sapply(myDFs, nrow)) 
   do.call(cbind, lapply(myDFs, function(x) rbind(x, matrix(,n-nrow(x), ncol(x)))))
}

Поскольку у вас есть rows и список, вам нужно использовать rbind и преобразовать элемент вашегосписок до data.frame, прежде чем связывать их вместе.

newDF <- data.frame()
for(i in 1:length(myList)){
   tmp <- as.data.frame(myList[[i]])
   names(tmp) <- names(myList[i])
   newDF <- cbind.NA(newDF,tmp) 
}

newDF
      a b  c
[1,]  1 4  9
[2,]  2 5 10
[3,]  3 6 NA
[4,] NA 7 NA

t(newDF)
   [,1] [,2] [,3] [,4]
a    1    2    3   NA
b    4    5    6    7
c    9   10   NA   NA
0 голосов
/ 24 сентября 2019

При таком подходе ваш Value сохраняется в виде списка:

myDF <- data.frame(t(rbind(myList)))

myDF
#      myList
#a    1, 2, 3
#b 4, 5, 6, 7
#c      9, 10

str(myDF)
#'data.frame':  3 obs. of  1 variable:
# $ myList:List of 3
#  ..$ a: num  1 2 3
#  ..$ b: num  4 5 6 7
#  ..$ c: num  9 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...