Eu tenho um data.frame que gostaria de converter em uma lista por linhas, o que significa que cada linha corresponderia aos seus próprios elementos de lista. Em outras palavras, eu gostaria de uma lista que contenha o data.frame com linhas.
Até agora, lidei com esse problema da seguinte maneira, mas fiquei pensando se há uma maneira melhor de abordar isso.
xy.df <- data.frame(x = runif(10), y = runif(10))
# pre-allocate a list and fill it with a loop
xy.list <- vector("list", nrow(xy.df))
for (i in 1:nrow(xy.df)) {
xy.list[[i]] <- xy.df[i,]
}
split
cada elemento, ele tem o tipo emdata.frame with 1 rows and N columns
vez de #list of length N
split
, provavelmente deverá fazer odrop=T
contrário, seus níveis originais de fatores não cairãoEureka!
fonte
unlist(apply(xy.df, 1, list), recursive = FALSE)
. No entanto, a solução do flodel é mais eficiente do que usarapply
ort
.t
converte adata.fame
emmatrix
para que os elementos em sua lista sejam vetores atômicos, não listados como o OP solicitado. Normalmente não é um problema até que o seuxy.df
contém tipos mistos ...apply
. Na verdade, é apenas um loop for implementado em R.lapply
executa o loop em C, que é significativamente mais rápido. Esse formato de lista de linhas é realmente preferível se você estiver fazendo muitas repetições.apply
versão é.mapply(data.frame, xy.df, NULL)
Se você deseja abusar completamente do data.frame (como eu) e gostaria de manter a funcionalidade $, uma maneira é dividir seu data.frame em uma linha data.frames reunidos em uma lista:
Não é apenas masturbação intelectual, mas permite 'transformar' o data.frame em uma lista de suas linhas, mantendo a indexação $ que pode ser útil para uso posterior com lapply (assumindo que a função que você passa para lapply use essa indexação $)
fonte
data.frame
s em um únicodata.frame
?Uma solução mais moderna usa apenas
purrr::transpose
:fonte
Eu estava trabalhando nisso hoje para um data.frame (realmente um data.table) com milhões de observações e 35 colunas. Meu objetivo era retornar uma lista de data.frames (data.tables), cada uma com uma única linha. Ou seja, eu queria dividir cada linha em um data.frame separado e armazená-los em uma lista.
Aqui estão dois métodos que eu criei que eram aproximadamente três vezes mais rápidos do que
split(dat, seq_len(nrow(dat)))
para esse conjunto de dados. Abaixo, comparo os três métodos em um conjunto de dados de 5 colunas e 7500 linhas, com 7500 linhas ( íris repetida 50 vezes).Isso retorna
Embora as diferenças não sejam tão grandes quanto no meu teste anterior, o
setDF
método direto é significativamente mais rápido em todos os níveis da distribuição de execuções com max (setDF) <min (split) e oattr
método geralmente é mais do que o dobro da velocidade.Um quarto método é o campeão extremo, que é um simples aninhado
lapply
, retornando uma lista aninhada. Este método exemplifica o custo de construção de um data.frame a partir de uma lista. Além disso, todos os métodos que tentei com adata.frame
função eram aproximadamente uma ordem de magnitude mais lenta que asdata.table
técnicas.dados
fonte
Parece que uma versão atual do
purrr
pacote (0.2.2) é a solução mais rápida:Vamos comparar as soluções mais interessantes:
Resultados:
Também podemos obter o mesmo resultado com
Rcpp
:Agora compare com
purrr
:Resultados:
fonte
by_row()
foi agora transferido paralibrary(purrrlyr)
Mais algumas opções:
Com
asplit
Com
split
erow
dados
fonte
A melhor maneira para mim foi:
Dados de exemplo:
Chamamos a
BBmisc
bibliotecaE o resultado será:
fonte
Uma maneira alternativa é converter o df em uma matriz e aplicar a
lappy
função de aplicação de lista sobre ela:ldf <- lapply(as.matrix(myDF), function(x)x)
fonte
Outra alternativa de uso
library(purrr)
(que parece ser um pouco mais rápida em grandes data.frames)fonte
Como o @flodel escreveu: Isso converte seu quadro de dados em uma lista que possui o mesmo número de elementos que o número de linhas no quadro de dados:
Além disso, você pode adicionar uma função para selecionar apenas as colunas que não são NA em cada elemento da lista:
fonte
A
by_row
função dopurrrlyr
pacote fará isso por você.Este exemplo demonstra
Por padrão, o valor retornado de
myfn
é colocado em uma nova coluna da lista no df chamado.out
. O$.out
no final da instrução acima seleciona imediatamente essa coluna, retornando uma lista de listas.fonte