Мне нужно объединить два кадра данных. Первый из них выглядит следующим образом:Слияние кадров данных с предсказуемыми опечатками
> df1 <- data.frame(Artist = c("Vincent van ", "Vincent van ", "Theo van Gogh", "Alexandre", "Alexandre"), Location = c("a","a","a","b","c"), time = c(1,2,1,1,1))
> df1
Artist Location time
1 Vincent van a 1
2 Vincent van a 2
3 Theo van Gogh a 1
4 Alexandre b 1
5 Alexandre c 1
И второе:
> df2 <- data.frame(Artist = c("Vincent van Gogh", "Theo van Gogh", "Alexandre Dumas", "Alexandre Dumas"), HomeNumber = c(123,234,456,789), Location = c("a","a","b","c"))
> df2
Artist HomeNumber Location
1 Vincent van Gogh 123 a
2 Theo van Gogh 234 a
3 Alexandre Dumas 456 b
4 Alexandre Dumas 789 c
И я хочу этот кадр данных:
> df3 <- data.frame(Artist = c("Vincent van ", "Vincent van ", "Theo van Gogh", "Alexandre", "Alexandre"), Location = c("a","a","a","b","c"), time = c(1,2,1,1,1), HomeNumber = c(123,123,234,456,789))
> df3
Artist Location time HomeNumber
1 Vincent van a 1 123
2 Vincent van a 2 123
3 Theo van Gogh a 1 234
4 Alexandre b 1 456
5 Alexandre c 1 789
>
Объединение будет работать только для Тео:
> df3 <- merge(df1, df2, by.x = "Artist", by.y = "Artist", all.x =TRUE)
> df3
Artist Location.x time HomeNumber Location.y
1 Alexandre b 1 NA <NA>
2 Alexandre c 1 NA <NA>
3 Theo van Gogh a 1 234 a
4 Vincent van a 1 NA <NA>
5 Vincent van a 2 NA <NA>
Причина двоякая: (a) У Винсента отсутствует его фамилия в df1
. (b) Александр - имя Александра Дюма старший и младший Александр Дюма.
Я могу решить (а) с df1$Artist <- gsub("Vincent van $","Vincent van Gogh", df1$Artist)
, но мои данные на самом деле очень большие, и перед выполнением gsub
Я должен сначала узнать полное имя Винсента. Одним из возможных решений могло бы быть использование grep("Vincent van "...
в df2, построить функцию, которая, если длина результирующего вектора равна 1
, я бы использовал gsub
для использования возвращаемого df2$Artist
в df1
. Я не знаю, как это сделать.
(b) немного сложнее для меня. Одно из решений, которое я могу придумать (но не могу кодировать), - это использовать функцию if
, чтобы сначала выбрать Alexandre из одного места, а затем использовать решение для (a) до gsub
имени.
Я думаю, что решение (a) и (b) вернет мой желаемый df3
. Вы, ребята, знаете, как я могу эффективно объединить эти данные? Благодаря!
EDIT: Обратите внимание, что Alexandre
фактически представляет собой два разных устройства. Таким образом, при слиянии двух из них должны быть связанные с ними HomeNumber и Location. Vincent
- это единое целое, но с двумя наблюдениями во времени.
вы можете попробовать с 'матчем()' функцией, где вы можете поместить 'location' в качестве аргумента матча и остальных столбцов, чтобы показать в новом data.frame – Duck
Функция 'agrep' выполняет нечеткое соответствие строк. Вы также можете выполнить несколько шагов, таких как «tolower» и удаление знаков препинания, чтобы помочь ... Но самый короткий ответ заключается в том, что обработка данных утомительна! – Justin
@ Duck: Это может помочь, но я не вижу, как это решит проблему. Благодаря! @Justin: Я знаю! Чрезвычайно утомительный. Я уже использовал 'tolower',' chartr' и некоторые другие функции. – Lucarno