У меня есть список многих data.frames, которые я хочу объединить. Проблема здесь в том, что каждый data.frame отличается количеством строк и столбцов, но все они имеют общие ключевые переменные (которые я вызывал "var1"
и "var2"
в коде ниже). Если бы data.frames были идентичны с точки зрения столбцов, я мог бы просто rbind
сказать, для чего plyr rbind.fill сделает свою работу, но с этими данными дело обстоит иначе .
Поскольку merge
команда работает только на 2 data.frames, я обратился к Интернету за идеями. Я получил это один из здесь , который прекрасно работал в R 2.7.2, который является то , что я имел в то время:
merge.rec <- function(.list, ...){
if(length(.list)==1) return(.list[[1]])
Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}
И я бы назвал функцию так:
df <- merge.rec(my.list, by.x = c("var1", "var2"),
by.y = c("var1", "var2"), all = T, suffixes=c("", ""))
Но в любой версии R после 2.7.2, включая 2.11 и 2.12, этот код завершается ошибкой со следующей ошибкой:
Error in match.names(clabs, names(xi)) :
names do not match previous names
(Кстати, я вижу другие ссылки на эту ошибку в другом месте без разрешения).
Есть ли способ решить это?
map_dfr()
илиmap_dfc()
dfs = [df1, df2, df3]
затемreduce(pandas.merge, dfs)
.Уменьшить делает это довольно легко:
Вот полный пример использования некоторых фиктивных данных:
А вот пример использования этих данных для репликации
my.list
:Примечание: похоже, что это, возможно, ошибка в
merge
. Проблема в том, что нет проверки, что добавление суффиксов (для обработки перекрывающихся несовпадающих имен) фактически делает их уникальными. В определенный момент он использует,[.data.frame
который делаетmake.unique
имена, вызываяrbind
сбой.Самый простой способ исправить это не оставлять переименование полей для полей дубликатов (которых здесь много) до
merge
. Например:merge
/Reduce
Будет тогда работать нормально.источник
empty <- data.frame(x=numeric(0),a=numeric(0); L3 <- c(empty,empty,list.of.data.frames,empty,empty,empty)
и случилось что-то странное, чего я еще не понял.Вы можете сделать это , используя
merge_all
вreshape
пакете. Вы можете передать параметры,merge
используя...
аргументВот отличный ресурс по различным методам объединения фреймов данных .
источник
Вы можете использовать рекурсию, чтобы сделать это. Я не проверял следующее, но это должно дать вам правильную идею:
источник
Я буду использовать пример данных из @PaulRougieux
Вот короткое и сладкое решение с использованием
purrr
иtidyr
источник
Функция
eat
моего пакета safejoin имеет такую функцию, если вы передадите ей список data.frames в качестве второго входа, он рекурсивно присоединит их к первому входу.Заимствование и распространение данных принятого ответа:
Нам не нужно брать все столбцы, мы можем использовать помощники select из tidyselect и select (поскольку мы начинаем со
.x
всех.x
сохраненных столбцов):или удалить конкретные:
Если список назван, имена будут использоваться в качестве префиксов:
Если есть конфликты столбцов,
.conflict
аргумент позволяет вам разрешить его, например, взяв первый / второй, добавив их, объединив их или вложив.держись первым:
держать в прошлом:
Добавить:
COALESCE:
гнездо:
NA
значения могут быть заменены с помощью.fill
аргумента.По умолчанию это усовершенствованный ,
left_join
но весь dplyr присоединяется поддерживается с помощью.mode
аргумента, нечеткий присоединяется также поддерживаются черезmatch_fun
аргумент (это обернуто вокруг пакетаfuzzyjoin
) или дают формулу , например , как~ X("var1") > Y("var2") & X("var3") < Y("var4")
кby
аргументу.источник
У меня был список фреймов данных без общего столбца идентификатора.
У меня отсутствовали данные о многих DFS. Были нулевые значения. Кадры данных были созданы с использованием табличной функции. Снижение, объединение, rbind, rbind.fill и тому подобное не могли помочь мне достичь цели. Моя цель состояла в том, чтобы создать понятный объединенный фрейм данных, не имеющий отношения к отсутствующим данным и общему столбцу идентификаторов.
Поэтому я сделал следующую функцию. Может быть, эта функция может кому-то помочь.
это следует за функцией
Запуск примера
источник
Если у вас есть список dfs, а столбец содержит «ID», но в некоторых списках некоторые идентификаторы отсутствуют, вы можете использовать эту версию Reduce / Merge для объединения нескольких Dfs с отсутствующими идентификаторами строк или метками:
источник
Вот общая оболочка, которая может быть использована для преобразования двоичной функции в функцию с несколькими параметрами. Преимущество этого решения в том, что оно очень универсально и может применяться к любым двоичным функциям. Вам просто нужно сделать это один раз, а затем вы можете применить его в любом месте.
Чтобы продемонстрировать идею, я использую простую рекурсию для реализации. Конечно, это может быть реализовано более элегантным способом, который выигрывает от хорошей поддержки функциональной парадигмы R.
Затем вы можете просто обернуть в нее любые двоичные функции и вызвать их с позиционными параметрами (обычно data.frames) в первых скобках, а именованные параметры - во вторых скобках (например,
by =
orsuffix =
). Если именованных параметров нет, оставьте вторые скобки пустыми.источник