#r #dplyr
Вопрос:
У меня есть таблица, содержащая буквы и цифры:
xx lt;- tibble (letter = c (rep ("a", 3), rep ("b", 3), rep ("c", 3)), number = c (1, 2, 3, 1, 2, 3, 4, 5, 6))
Я хотел бы сначала сгруппировать данные по «букве», а затем проверить, есть ли какие-либо две группы, которые имеют одинаковые значения в числовом столбце. Это будут группы с буквами «а» и «в» в столбце «буква».
Результат будет выглядеть так
xx lt;- tibble (letter = c (rep ("a", 3), rep ("b", 3), rep ("c", 3)), number = c (1, 2, 3, 1, 2, 3, 4, 5, 6), duplicated = c (rep (TRUE, 6), rep (FALSE, 3)) )
есть ли способ сделать это элегантно в dplyr?
Ответ №1:
Вы можете использовать cur_group()
для подмножества xx
и проверки на герметичность:
library(dplyr) xx %gt;% group_by(letter) %gt;% mutate(duplicated = number %in% xx$number[!xx$letter %in% cur_group()]) %gt;% ungroup()
cur_group()
представляет значение текущей групповой переменной (напримерa
,b
,c
).- Мы используем значение
cur_group()
для подмножества вектораxx$number
для тех, кто не входит в текущую группу (!xx$letter %in% cur_group()
). - Наконец, мы проверяем, входит ли текущая группа
number
в это подмножество (number %in% ...
).
Выход
letter number duplicated lt;chrgt; lt;dblgt; lt;lglgt; 1 a 1 TRUE 2 a 2 TRUE 3 a 3 TRUE 4 b 1 TRUE 5 b 2 TRUE 6 b 3 TRUE 7 c 4 FALSE 8 c 5 FALSE 9 c 6 FALSE
Ответ №2:
Вы можете попробовать
xx %gt;% distinct() %gt;% group_by(number) %gt;% mutate(n = n()) %gt;% mutate(duplicated = ifelse(ngt;1, TRUE, FALSE)) %gt;% select(-n) letter number duplicated lt;chrgt; lt;dblgt; lt;lglgt; 1 a 1 TRUE 2 a 2 TRUE 3 a 3 TRUE 4 b 1 TRUE 5 b 2 TRUE 6 b 3 TRUE 7 c 4 FALSE 8 c 5 FALSE 9 c 6 FALSE
distinct
это для того, если внутри gruoup есть какие-то дубликаты,
xx lt;- tibble (letter = c (rep ("a", 4), rep ("b", 3), rep ("c", 3)), number = c (1,1, 2, 3, 1, 2, 3, 4, 4, 6)) letter number lt;chrgt; lt;dblgt; 1 a 1 2 a 1 3 a 2 4 a 3 5 b 1 6 b 2 7 b 3 8 c 4 9 c 4 10 c 6 xxx lt;- xx %gt;% distinct() %gt;% group_by(number) %gt;% mutate(n = n()) %gt;% mutate(duplicated = ifelse(ngt;1, TRUE, FALSE)) %gt;% select(-n) xx %gt;% full_join(xxx, by = c("letter", "number")) letter number duplicated lt;chrgt; lt;dblgt; lt;lglgt; 1 a 1 TRUE 2 a 1 TRUE 3 a 2 TRUE 4 a 3 TRUE 5 b 1 TRUE 6 b 2 TRUE 7 b 3 TRUE 8 c 4 FALSE 9 c 4 FALSE 10 c 6 FALSE
Спасибо @LMc
xxx lt;- xx %gt;% distinct() %gt;% add_count(number) %gt;% mutate(duplicated = ngt; 1) %gt;% select(-n) xxx xx %gt;% full_join(xxx, by = c("letter", "number"))
Комментарии:
1. Вы можете еще больше упростить, заменив
group_by(number) %gt;% mutate(n = n())
наadd_count(number)
.2. Также вам не нужно использовать
ifelse
, такngt;1
как это векторизованная операция, которая возвращает логический вектор.3. @LMc Я всегда скучаю по этому поводу. Большое спасибо.