Комбинация for-loop и ifelse в R

#r #for-loop #if-statement

#r #for-цикл #if-оператор

Вопрос:

Я пытаюсь выбрать между «Да» и «Нет» в R, если превышено определенное (и переменное) значение. Для каждого проверяемого значения должен быть создан новый столбец с различными решениями.

Вот созданный вручную пример:

 Test.data <- data.frame(c(10, 20, 30, 40, 50, 60, 70, 80, 90, 100))
colnames(Test.data) <- c("Test")

Test.data$Test1 <- ifelse(Test.data$Test > 10, "Yes", "No")
Test.data$Test2 <- ifelse(Test.data$Test > 20, "Yes", "No")
Test.data$Test3 <- ifelse(Test.data$Test > 30, "Yes", "No")

Test.data
 

Этот простой пример дает следующий результат:

    Test Test1 Test2 Test3
1    10    No    No    No
2    20   Yes    No    No
3    30   Yes   Yes    No
4    40   Yes   Yes   Yes
5    50   Yes   Yes   Yes
6    60   Yes   Yes   Yes
7    70   Yes   Yes   Yes
8    80   Yes   Yes   Yes
9    90   Yes   Yes   Yes
10  100   Yes   Yes   Yes
 

Есть ли способ сделать это с помощью for-loop? Я уже пробовал разные вещи, такие как следующий код, но это кажется бессмысленным, поскольку он не создает новые столбцы и так далее:

 n = c(seq(from=10, to=100, by=10))

for(i in n) {
ifelse(Test.data$Test > i, "Yes", "No")
}
 

Спасибо всем!

Ответ №1:

Мы можем выполнить присваивание ( <- ) выходных данных из ifelse строке, созданной с paste помощью имен столбцов. Кроме того, вместо зацикливания n мы выполняем цикл над последовательностью ‘n’

 for(i in seq_along(n)) {
        Test.data[paste0("Test", i)] <- ifelse(Test.data$Test > n[i], "Yes", "No")
 }
 

Ответ №2:

Возможно, вы можете попробовать что-то вроде приведенного ниже

 cbind(Test.data, ifelse(sapply(c(10, 20, 30), `<`, Test.data$Test), "Yes", "No"))
 

что дает

    Test   1   2   3
1    10  No  No  No
2    20 Yes  No  No
3    30 Yes Yes  No
4    40 Yes Yes Yes
5    50 Yes Yes Yes
6    60 Yes Yes Yes
7    70 Yes Yes Yes
8    80 Yes Yes Yes
9    90 Yes Yes Yes
10  100 Yes Yes Yes
 

Ответ №3:

Вы можете использовать purrr::map_dfc :

 vals <- c(10, 20, 30)

result <- cbind(Test.data, purrr::map_dfc(vals, 
                 ~ifelse(Test.data$Test > .x, 'Yes', 'No')))
names(result)[-1] <- paste0('Test', seq_along(vals))
result

#   Test Test1 Test2 Test3
#1    10    No    No    No
#2    20   Yes    No    No
#3    30   Yes   Yes    No
#4    40   Yes   Yes   Yes
#5    50   Yes   Yes   Yes
#6    60   Yes   Yes   Yes
#7    70   Yes   Yes   Yes
#8    80   Yes   Yes   Yes
#9    90   Yes   Yes   Yes
#10  100   Yes   Yes   Yes