#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 строки, данные содержат 104. Извините, я отредактировал решение …
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