Случай, когда по группе в Мутируют в R

#r

Вопрос:

Я новичок в R. поэтому мне нужна помощь в этой трансформации. У меня есть два стола:

 x1 lt;- c(7, 4, 4, 9, 2, 5, 8) x2 lt;- c(5, 2, 8, 9, 1, 3, 2) x3 lt;- c(6, 2, 3, 4, 2, 2, 7) objid lt;- c(1, 2, 3, 4, 4, 2, 4) data_1 lt;- data.frame(objid, x1, x2, x3)  

и второй столик:

 x1_r lt;- c(1.54,0.23, 1.32, 11.66) x2_r lt;- c(1.14,1.23, 9.32, 1.26) x3_r lt;- c(1.58,0.23, 7.32, 7.66) objid lt;- c(1, 2, 3, 4) data_2 lt;- data.frame(objid, x1_r, x2_r, x3_r)  

То, что я пытаюсь сделать в R, — это сделать СЛУЧАЙ по группе «objid» примерно так:

 CASE WHEN [x1] lt;=[x1_r] THEN 1 ELSE 0 CASE WHEN [x2] lt;=[x2_r] THEN 1 ELSE 0 CASE WHEN [x3] lt;=[x3_r] THEN 1 ELSE 0  

И создайте новые столбцы с результатами в data_2:

возражение x1 x2 x3 x1_r_fin x2_r_fin x3_r_fin
1 7 5 6 0 0 0
2 4 2 2 0 0 0
3 4 8 3 0 0 1
4 9 9 4 1 0 1
4 2 1 2 1 1 1
2 5 3 2 0 0 0
4 8 2 7 1 0 1

В mutate я применил этот метод:

 df %gt;% mutate_at(vars(-matches("objid")), list(Dif = ~ . - x1))  

Для простого вычитания и создания новых столбцов с новым именем на df. Я хочу сделать то же самое с вышеупомянутым выше, но понятия не имею, как и есть ли лучший и более эффективный метод. Спасибо за вашу помощь!

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

1. в пакете есть эквивалентная case_when функция dplyr , которая пришла из SQL CASE WHEN

2. Не уверен, что смогу последовать вашему примеру, поскольку data_2 присваивает objid значение .217 и другие значения В конце концов, все ваши xi_r_fin будут равны 0. Для самой операции вы можете работать с простым if-else: data_2 lt;- data_1 %gt;% mutate(x1_r_fin = if_else(x1 lt;= x1_r, 1, 0)) . Добавьте if_else() для x2 и x3, и вы должны быть хороши. ((Очевидно, это работает только в том случае, если вы хотите сравнить свои data_1 с отдельными значениями. В противном случае объедините с помощью join().

3. Привет @Рэй, извини за это. Я внес поправку в вопрос.

Ответ №1:

вы можете использовать функцию ifelse из базы R. В двух наборах данных есть разное количество raw, поэтому я сначала объединил их.

 new_data = merge(data_1, data_2, all = T)  

затем с помощью функции ifelse вы можете создавать новые переменные

 new_data$new_variable1 = ifelse(new_data$x1 lt; new_data$x1_r, 1, 0)  

кроме того, вы можете добавить строку в функцию ifelse

 new_data$new_variable2 = ifelse(new_data$x1 lt; new_data$x1_r, "group2", 0)  

затем, если вы хотите извлечь переменные из new_data

 new_data = new_data %gt;% select(-5,-6,7)   

или, как @NovaEthos, упомянутый в комментариях, вы можете использовать функцию case_when

 new_data$new_variable1 = case_when(new_data$x1 lt; new_data$x1_r ~ "group 1")  

однако после этого вам следует устранить NA.

Ответ №2:

Вот подход, использующий случай dplyr, когда:

 library(tidyverse) data_1 %gt;% inner_join(data_2, by='objid') %gt;% # join data_1 and data_2 by objid mutate(x1r_fin = case_when(x1 lt;= x1_r ~ 1,   TRUE~  0 )) %gt;%  mutate(x2r_fin = case_when(x2 lt;= x2_r ~ 1,   TRUE~  0 )) %gt;%  mutate(x3r_fin = case_when(x3 lt;= x3_r ~ 1,   TRUE~  0 )) %gt;% select(-c(x1_r, x2_r, x3_r))  

Для одномерных условий ifelse() также вполне читаем:

 merge(data_1, data_2, by='objid') -gt; data_1 data_1$x1_r_fin lt;- ifelse(data_1$x1 lt;= data_1$x1_r, 1, 0) data_1$x2_r_fin lt;- ifelse(data_1$x2 lt;= data_1$x2_r, 1, 0) data_1$x3_r_fin lt;- ifelse(data_1$x3 lt;= data_1$x3_r, 1, 0) data_1$x1_r lt;- NULL data_1$x2_r lt;- NULL data_1$x3_r lt;- NULL  

Вы также можете использовать ifelse с функцией mutate() а-ля:

 ... %gt;% mutate(x1r_fin = ifelse(x1 lt;= x1_r, 1, 0)) %gt;% ...  

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

1. Спасибо, Отто, это именно то, чего я хотел!

2. Рад, что помог. Не могли бы вы принять мой ответ? Большое спасибо!