#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
«.