#r
Вопрос:
Итак, с места в карьер я думаю, что мне нужно что-то вроде пакета R «fuzzyjoin», или, может быть, это действительно может сработать, но мне тогда нужна помощь в том, как заставить его работать.
У меня есть два фрейма данных df1 и df2. Каждый фрейм данных содержит 7 столбцов. Столбцы: идентификатор; тип 1; тип 2; критерии 1; критерии 2; критерии 3; критерии 4.
df1 имеет, скажем, 500 строк, в то время как df2 имеет, скажем, 2000 строк. Вот небольшой отрывок, чтобы прояснить, что я имею в виду.
df1
id type 1 type 2 criteria 1 criteria 2 criteria 3 criteria 4
214 CAF A 19.76338 44078 0.7 45904
312 BZD B 17.21671 43333 3.385 45159
df2
id type 1 type 2 criteria 1 criteria 2 criteria 3 criteria 4
66 CAF B 20.50012 43963 2.375 45058
163 CAF B 20.72327 42640 2.125 44466
188 CAF A 21.12873 41075 4.375 44727
250 CAF A 20.43558 43427 3.75 45253
345 CAF A- 18.45072 43669 10.4 45496
357 CAF A 20.72327 43046 2.75 44932
520 CAF AA 19.1687 41586 6.25 45238
609 CAF A 19.32814 42160 4.5 45813
637 CAF A- 19.32038 42808 4.5 46644
791 CAF AA 18.79739 42460 4.5 46295
846 BZD B 18.07695 43399 3.4 45225
854 BZD A 18.0598 43992 7.5 47644
885 BZD A 19.15586 42818 3.265 46470
1026 BZD B 18.9031 41694 3.925 47175
1045 BZD Aaa 17.49807 42412 0.45 46065
1121 BZD BB 18.12462 42087 0.68 45740
1176 BZD A 18.05427 41709 3.05 47553
Для каждой строки в df1 я хочу найти наиболее подходящую строку в df2, чтобы тип 1 и тип 2 были идентичны как для df1, так и для df2, а затем критерии от 1 до 4 были как можно ближе, но не обязательно должны быть точно идентичными (на самом деле они вряд ли будут). Предпочтительно, если возможно, я хотел бы использовать расстояние Махаланобиса для критериев, но это не является строго необходимым.
Кто-нибудь знает, какой пакет или функцию я могу использовать для этого?
Комментарии:
1. Пожалуйста, поделитесь воспроизводимым примером, вставив выходные
dput(df1)
данные иdput(df2))
в свой вопрос. Спасибо.
Ответ №1:
Вы можете сделать это следующим образом:
df1 = tribble(
~id, ~type1, ~type2, ~criteria1, ~criteria2, ~criteria3, ~criteria4,
1, "CAF","A ", 19.76338, 44078, 0.7, 45904,
2, "BZD","B ", 17.21671, 43333, 3.385, 45159,
3, "CAF", "A ", 22.12873, 45075, 4.365, 42727,
4, "BZD","B ", 15.21671, 43333, 3.385, 45159,
5, "BZD","B ", 16.21671, 43333, 3.385, 45159
)
df2 = tribble(
~id, ~type1, ~type2, ~criteria1, ~criteria2, ~criteria3, ~criteria4,
66, "CAF", "B ", 20.50012, 43963, 2.375, 45058,
163, "CAF", "B", 20.72327, 42640, 2.125, 44466,
188, "CAF", "A ", 21.12873, 41075, 4.375, 44727,
250, "CAF", "A ", 20.43558, 43427, 3.75, 45253,
345, "CAF", "A-", 18.45072, 43669, 10.4, 45496,
357, "CAF", "A ", 20.72327, 43046, 2.75, 44932,
520, "CAF", "AA", 19.1687, 41586, 6.25, 45238,
609, "CAF","A ", 19.32814, 42160, 4.5, 45813,
637, "CAF", "A-", 19.32038, 42808, 4.5, 46644,
791, "CAF", "AA", 18.79739, 42460, 4.5, 46295,
846, "BZD", "B ", 18.07695, 43399, 3.4, 45225,
854, "BZD", "A ", 18.0598, 43992, 7.5, 47644,
885, "BZD", "A ", 19.15586, 42818, 3.265, 46470,
1026, "BZD","B ", 18.9031, 41694, 3.925, 47175,
1045, "BZD", "Aaa", 17.49807, 42412, 0.45, 46065,
1121, "BZD", "BB", 18.12462, 42087, 0.68, 45740,
1176, "BZD","A ", 18.05427, 41709, 3.05, 47553
)
addCrit = function(df_1, df_2){
df_2 %>%
filter(type1==df_1$type1 amp; type2==df_1$type2) %>%
nest(data=criteria1:criteria4) %>%
mutate(
crit = map_dbl(data, crit, df_1),
id2 = id
) %>%
arrange(crit) %>%
select(id2, crit) %>%
head(1)
}
crit = function(df1, df2) sqrt(
(df1$criteria1-df2$criteria1)^2
(df1$criteria2-df2$criteria2)^2
(df1$criteria3-df2$criteria3)^2
(df1$criteria4-df2$criteria4)^2)
df1 %>%
nest(data=type1:criteria4) %>%
mutate(
cr = map(data, addCrit, df2)
) %>% unnest(c(cr, data))
выход
# A tibble: 5 x 9
id type1 type2 criteria1 criteria2 criteria3 criteria4 id2 crit
<dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 CAF A 19.8 44078 0.7 45904 250 921.
2 2 BZD B 17.2 43333 3.38 45159 846 93.3
3 3 CAF A 22.1 45075 4.36 42727 357 2996.
4 4 BZD B 15.2 43333 3.38 45159 846 93.4
5 5 BZD B 16.2 43333 3.38 45159 846 93.4
Сделайте crit
функцию так, как вы считаете нужным. Это может быть критерий Махаланобиса или что-то еще.
Эта функция принимает два однострочных фрейма данных и возвращает значение критерия в виде double
значения.
Комментарии:
1. Привет. Я пытаюсь сделать это с гораздо большим набором данных и получаю следующую ошибку. Это потому, что происходит слишком много возможных совпадений, или в чем проблема? ` Ошибка: Проблема с
mutate()
колонкойcr
. icr = map(data, addCrit, df2)
. проблема x соmutate()
столбцомcrit
. icrit = map_dbl(data, crit, df_1)
. Результат x 1 должен быть одинарным двойным, а не двойным вектором длины 9rlang::last_error()
, чтобы увидеть, где произошла ошибка. `2. Проверьте чистоту ваших данных. Вы уверены
criteria1: criteria4
, что переменные будут содержать толькоdbl
значения?3. Таким образом , используя
typeof()
иclass()
, каждый изcriteria1:criteria4
них, по-видимомуdouble
, иnumeric
. Следовательно, я думаю, что типы данных должны быть правильными?4. Можете ли вы тогда поделиться со мной этими данными? Я проверю это для тебя. Если по какой-то причине вы не можете поделиться со мной данными, разделите их пополам и протестируйте, когда получите сообщение об ошибке. Повторите это деление пополам, что приведет к ошибке. Таким образом, вы быстро определите проблему.