Условие Ifelse для нескольких переменных с использованием функции paste0 для вызова переменных

#r

#r

Вопрос:

Я хочу использовать условие ifelse для нескольких переменных,используя paste0(«Var», c(1,3,5)) для вызова переменных. Вот некоторые данные.

 set.seed(123) df lt;- data.frame(Var1 = sample(1:5,10,replace = T),  Var2 = sample(1:5,10,replace = T),  Var3 = sample(1:5,10,replace = T),  Var4 = sample(1:5,10,replace = T),  Var5 = sample(1:5,10,replace = T))  df  Var1 Var2 Var3 Var4 Var5 1 3 5 2 1 5 2 3 3 1 1 5 3 2 3 3 2 4 4 2 1 4 3 5 5 3 4 1 4 2 6 5 1 3 5 1 7 4 1 5 5 1 8 1 5 4 3 3 9 2 3 2 1 1 10 3 2 5 2 5  

В качестве примера меня интересуют Var1, Var3, Var5. Используя ifelse, если значение равно 4,5, новой переменной присваивается значение 1, иначе 0. Я использую код для получения переменных, которые меня интересуют.

 paste0( "Var", c(1,3,5) )  [1] "Var1" "Var3" "Var5"  

Я пробовал и то, и другое, и знаю, что это не работает, но можно ли написать код, похожий на этот

 newvar lt;- ifelse( paste0("Var", c(1,3,5)) %in% c(4,5) , 1, 0)  newvar lt;- ifelse( df[ , paste0( "Var", c(1:3) ) ] %in% c(4,5) , 1, 0)   

Любая помощь будет очень признательна. Спасибо

ОТРЕДАКТИРОВАНО : Извиняюсь, если не было ясно. Я создавал ifelse для нескольких переменных, чтобы создать одну переменную. «newvar» — это одна переменная, я не хотел создавать ifelse для каждой переменной newvar1, newvar3, newvar5. Это любое значение 4 или 5 в любой из этих переменных, newvar равно 1 или 0. Спасибо

Ответ №1:

Используйте сапфир:

 v lt;- paste0("Var", c(1, 3, 5)) # or v lt;- c(1, 3, 5) cbind(df, new =  sapply(df[v], `%in%`, 4:5))  

дающий:

 Var1 Var2 Var3 Var4 Var5 new.Var1 new.Var3 new.Var5 1 3 5 2 1 5 0 0 1 2 3 3 1 1 5 0 0 1 3 2 3 3 2 4 0 0 1 4 2 1 4 3 5 0 1 1 5 3 4 1 4 2 0 0 0 6 5 1 3 5 1 1 0 0 7 4 1 5 5 1 1 1 0 8 1 5 4 3 3 0 1 0 9 2 3 2 1 1 0 0 0 10 3 2 5 2 5 0 1 1  

Добавлен

Что касается комментария под этим ответом, попробуйте любой из них. Все они используют v, определенный в следующей строке, за исключением последнего решения.

 v lt;- paste0("Var", c(1, 3, 5)) # or v lt;- c(1, 3, 5) transform(df, newvar = do.call("pmax", lapply(df[v], `%in%`, 4:5)))  transform(df, newvar = apply(df[v] == 4 | df[v] == 5, 1, max))  transform(df, newvar = apply(df[v], 1, function(x)  any(x %in% 4:5)))  transform(df, newvar = pmax(Var1 %in% 4:5, Var3 %in% 4:5, Var5 %in% 4:5))  

любой из которых дает:

 Var1 Var2 Var3 Var4 Var5 newvar 1 3 5 2 1 5 1 2 3 3 1 1 5 1 3 2 3 3 2 4 1 4 2 1 4 3 5 1 5 3 4 1 4 2 0 6 5 1 3 5 1 1 7 4 1 5 5 1 1 8 1 5 4 3 3 1 9 2 3 2 1 1 0 10 3 2 5 2 5 1  

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

1. Очень полезно, но приношу извинения, если не было ясно. Я создавал ifelse для нескольких переменных, чтобы создать одну переменную. «newvar» — это единственная переменная, не отличающаяся от newvar1, newvar3, newvar5. Я отредактировал исходный вопрос. Спасибо

2. ОК. Добавлены 2 подхода в Добавленном разделе.

Ответ №2:

Вот решение, основанное на tidyverse.

 library(tidyverse)  df %gt;%   mutate(  across(  c(Var1, Var3, Var5),   ~ifelse(.x %in% c(4, 5), 1, 0),   .names="new{.col}"  )  )  Var1 Var2 Var3 Var4 Var5 newVar1 newVar3 newVar5 1 3 5 2 1 5 0 0 1 2 3 3 1 1 5 0 0 1 3 2 3 3 2 4 0 0 1 4 2 1 4 3 5 0 1 1 5 3 4 1 4 2 0 0 0 6 5 1 3 5 1 1 0 0 7 4 1 5 5 1 1 1 0 8 1 5 4 3 3 0 1 0 9 2 3 2 1 1 0 0 0 10 3 2 5 2 5 0 1 1  

across Функция выполняет функцию, определенную в ее втором аргументе, для каждого из столбцов, определенных ее первым аргументом. .names Аргумент является необязательным и предоставляет имена для новых столбцов (в отличие от перезаписи оригиналов). {.col} является заполнителем для имени текущего столбца.

Ответ №3:

Вот base R решение, близкое к тому, что пробовал ОП:

 df$newVar lt;- sapply(df[,c(1,3,5)], function(x) ifelse(x == 4|x == 5, 1, 0))  

или, еще ближе:

 df$newVar lt;- sapply(df[,c(1,3,5)], function(x) ifelse(x %in% c(4,5), 1, 0))  

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

1. спасибо за это, я определенно могу его использовать, но есть ли что-то проще. Приношу извинения, если не было ясно. Я создавал ifelse для нескольких переменных, чтобы создать одну переменную. «newvar» — это отдельная переменная, а не newvar1, newvar3, newvar5. Я отредактирую исходный вопрос. Спасибо

2. Отредактировали ответ…

3. На это я получаю сообщение об ошибке. Ошибка в $lt;-.data.frame ( *tmp* , newVar, значение = список(Var1 = c(0, 0, : замена содержит 3 строки, данные содержат 10

4. Извините, я отредактировал решение …

5. закройте, он создает новый файл, но он содержит 3 переменные списка. Спасибо

Ответ №4:

Если вы хотите использовать оба paste0() и ifelse() , вот пример:

 x lt;- paste0("Var", c(1,3,5)) newvar lt;- matrix(NA, nrow(df1), length(x))  for(j in 1:(length(x))){  newvar[,j] lt;- ifelse(df1[ ,x[j]] %in% c(4,5), 1, 0)}  final.df lt;- data.frame(df1,   newvar=ifelse(apply(newvar, 1, sum)gt;0, 1, 0 )) final.df   Var1 Var2 Var3 Var4 Var5 newvar 1 3 5 2 1 5 1 2 3 3 1 1 5 1 3 2 3 3 2 4 1 4 2 1 4 3 5 1 5 3 4 1 4 2 0 6 5 1 3 5 1 1 7 4 1 5 5 1 1 8 1 5 4 3 3 1 9 2 3 2 1 1 0 10 3 2 5 2 5 1