Eu tenho uma lista de muitos data.frames que quero mesclar. O problema aqui é que cada data.frame difere em termos de número de linhas e colunas, mas todos compartilham as principais variáveis (que eu chamei "var1"
e "var2"
no código abaixo). Se os data.frames fossem idênticos em termos de colunas, eu poderia apenas rbind
, para qual rbind.fill do plyr faria o trabalho, mas esse não é o caso com esses dados.
Como o merge
comando funciona apenas em 2 data.frames, procurei idéias na Internet. Eu peguei esse daqui , que funcionou perfeitamente no R 2.7.2, que era o que eu tinha na época:
merge.rec <- function(.list, ...){
if(length(.list)==1) return(.list[[1]])
Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}
E eu chamaria a função assim:
df <- merge.rec(my.list, by.x = c("var1", "var2"),
by.y = c("var1", "var2"), all = T, suffixes=c("", ""))
Mas em qualquer versão R após 2.7.2, incluindo 2.11 e 2.12, esse código falha com o seguinte erro:
Error in match.names(clabs, names(xi)) :
names do not match previous names
(Incidentemente, vejo outras referências a esse erro em outro lugar sem resolução).
Existe alguma maneira de resolver isto?
map_dfr()
oumap_dfc()
dfs = [df1, df2, df3]
seguidareduce(pandas.merge, dfs)
.Reduzir torna isso bastante fácil:
Aqui está um exemplo completo usando alguns dados simulados:
E aqui está um exemplo usando esses dados para replicar
my.list
:Nota: Parece que isso é um problema
merge
. O problema é que não há verificação de que adicionar os sufixos (para lidar com nomes não correspondentes sobrepostos) realmente os torna únicos. Em um certo momento ele usa[.data.frame
que fazmake.unique
os nomes, fazendo com que arbind
falhar.A maneira mais fácil de corrigir é não deixar o campo renomeando para campos duplicados (dos quais existem muitos aqui) até
merge
. Por exemplo:O
merge
/Reduce
funcionará bem.fonte
empty <- data.frame(x=numeric(0),a=numeric(0); L3 <- c(empty,empty,list.of.data.frames,empty,empty,empty)
e aconteceu algumas coisas estranhas que ainda não descobri.Você pode fazer isso usando
merge_all
oreshape
pacote. Você pode passar parâmetros paramerge
usar o...
argumentoAqui está um excelente recurso sobre métodos diferentes para mesclar quadros de dados .
fonte
Você pode usar a recursão para fazer isso. Não verifiquei o seguinte, mas ele deve lhe dar a idéia certa:
fonte
Vou reutilizar o exemplo de dados de @PaulRougieux
Aqui está uma solução curta e agradável usando
purrr
etidyr
fonte
A função
eat
do meu pacote safejoin possui esse recurso, se você fornecer uma lista de data.frames como segunda entrada, ela os juntará recursivamente à primeira entrada.Emprestando e estendendo os dados da resposta aceita:
Não precisamos pegar todas as colunas, podemos usar auxiliares selecionados de tidyselect e escolher (à medida que partimos de
.x
todas as.x
colunas são mantidas):ou remova os específicos:
Se a lista for nomeada, os nomes serão usados como prefixos:
Se houver conflito de colunas, o
.conflict
argumento permitirá que você o resolva, por exemplo, pegando o primeiro / segundo, adicionando-os, juntando-os ou aninhando-os.mantenha primeiro:
mantenha por último:
adicionar:
coalescer:
ninho:
NA
valores podem ser substituídos usando o.fill
argumentoPor padrão, é um aprimorado,
left_join
mas todas as junções dplyr são suportadas por meio do.mode
argumento, junções difusas também são suportadas por meio domatch_fun
argumento (está agrupado em torno do pacotefuzzyjoin
) ou fornecendo uma fórmula como~ X("var1") > Y("var2") & X("var3") < Y("var4")
a doby
argumento.fonte
Eu tinha uma lista de quadros de dados sem coluna de identificação comum.
Eu tinha dados perdidos em muitos dfs. Havia valores nulos. Os quadros de dados foram produzidos usando a função de tabela. O Reduzir, Mesclar, rbind, rbind.fill e similares não poderiam me ajudar a atingir meu objetivo. Meu objetivo era produzir um quadro de dados mesclado compreensível, irrelevante dos dados ausentes e da coluna de identificação comum.
Portanto, eu fiz a seguinte função. Talvez essa função possa ajudar alguém.
está seguindo a função
Executando o exemplo
fonte
Quando você possui uma lista de dfs e uma coluna contém o "ID", mas em algumas listas faltam alguns IDs, você pode usar esta versão do Reduce / Merge para associar vários Dfs de IDs ou rótulos de linha ausentes:
fonte
Aqui está um wrapper genérico que pode ser usado para converter uma função binária em função de vários parâmetros. O benefício desta solução é que ela é muito genérica e pode ser aplicada a qualquer função binária. Você só precisa fazer uma vez e depois pode aplicá-lo em qualquer lugar.
Para demonstrar a ideia, eu uso a recursão simples para implementar. É claro que pode ser implementado de maneira mais elegante que se beneficia do bom suporte de R ao paradigma funcional.
Em seguida, você pode simplesmente envolver todas as funções binárias com ele e chamar com parâmetros posicionais (geralmente data.frames) nos primeiros parênteses e parâmetros nomeados nos segundos parênteses (como
by =
ousuffix =
). Se nenhum parâmetro nomeado, deixe os segundos parênteses vazios.fonte