Сопоставление значений двух кадров данных на основе множества условий в R

#r #dataframe #if-statement #dplyr #tidyverse

Вопрос:

У меня есть два набора данных

 cycle lt;- c(160, 160, 150, 158, 180)  split1 lt;- c(2, 2,4, 6, 8)  split2 lt;- c(10,10, 12, 14, 16)  df1 lt;- data.frame(cycle, split1, split2)  df1  cycle split1 split2 1 160 2 10 2 160 2 10 3 150 4 12 4 158 6 14 5 180 8 16  cycle lt;- c(160,150,190,180,161,150,140,179) split1 lt;- c(2,4,12,8,2,4,32,8) split2 lt;- c(10, 12, 18, 16, 10, 12, 21, 16) df2 lt;- data.frame(cycle, split1, split2) df2  cycle split1 split2 1 160 2 10 2 150 4 12 3 190 12 18 4 180 8 16 5 161 2 10 6 150 4 12 7 140 32 21 8 179 8 16  

Я хочу сопоставить значения df1 и df2 и пометить значения df2 на основе двух условий:

1 — Если значения всех трех столбцов, т. е. цикл, разделение1 и разделение2, точно совпадают, то назначьте строку с меткой «То же самое», в противном случае «Другое».

2 — Если разница только в значении цикла от df1 и df2 составляет 1 или -1, а остальные значения строк одинаковы, то назначьте строку с меткой «То же самое», в противном случае «Другое».

Результат должен выглядеть следующим образом

 cycle split1 split2 Type 1 160 2 10 Same 2 150 4 12 Same 3 190 12 18 Different 4 180 8 16 Same 5 161 2 10 Same 6 150 4 12 Same 7 140 32 21 Different 8 179 8 16 Same  

Мне удалось выполнить первое условие, как показано ниже

 df1lt;- df1 %gt;% mutate(key = paste0(cycle,split1, split2, "_")) df2lt;- df2 %gt;% mutate(key = paste0(cycle,split1, split2, "_")) df2 %gt;% mutate(Type = ifelse(df2$key %in% df1$key, 'same', 'different'))%gt;%  select(-key)   cycle split1 split2 Type 1 160 2 10 same 2 150 4 12 same 3 190 12 18 different 4 180 8 16 same 5 161 2 10 different 6 150 4 12 same 7 140 32 21 different 8 179 8 16 different  

но возникли проблемы с достижением второго.

Есть идеи, как это сделать эффективно?

Заранее спасибо.

Ответ №1:

Основываясь на вашем оригинале df1 и df2 (без создания новой колонки key ), вы могли бы использовать

 df2 %gt;%   mutate(rn = row_number()) %gt;%   left_join(df1, by = c("split1", "split2"), suffix = c("", ".y")) %gt;%   mutate(  type = coalesce(  ifelse(abs(cycle - cycle.y) lt;= 1, "same", "different"),   "different")  ) %gt;%   group_by(rn) %gt;%   distinct() %gt;%   ungroup() %gt;%   select(-rn, -cycle.y)  

Это возвращает

 # A tibble: 8 x 4  cycle split1 split2 type   lt;dblgt; lt;dblgt; lt;dblgt; lt;chrgt;  1 160 2 10 same  2 150 4 12 same  3 190 12 18 different 4 180 8 16 same  5 161 2 10 same  6 150 4 12 same  7 140 32 21 different 8 179 8 16 same   

Комментарии:

1. Есть одна проблема. В фактических данных df1 имеет повторяющиеся значения, которые создают повторяющиеся значения в df2, которые мне не нужны. Я хочу, чтобы размер файла df2 был таким же.

2. Не могли бы вы привести пример с этой проблемой и объяснить, как с ней справиться?

3. например, если df1 равен : цикл lt;- c(160, 160, 150, 158, 180) split1 lt;- c(2, 2,4, 6, 8) split2 lt;- c(10,10, 12, 14, 16) df1 Тогда предоставленный вами код приведет к созданию 10 строк вместо 8.

4. Не уверен, что это то, что вы ищете: попробуйте заменить df1 в приведенном выше коде на df1 %gt;% distinct() .

5. Это дает ошибку «Проблема с добавлением вычисляемых столбцов distinct() . x Проблема с mutate() вводом ..1 «.