Есть ли способ заменить значение переменной в строке, если определенное условие выполнено, и повторить это для всего фрейма данных? - PullRequest
1 голос
/ 14 января 2020

У меня есть такой фрейм данных

main <- round(runif(100,min = 1, max = 5 ))
a1 <- rep(1, 100)
a2 <- rep(1, 100)
a3 <- rep(1, 100)
a4 <- rep(1, 100)
a5 <- rep(1, 100)

df <- data.frame(main, a1, a2, a3, a4, a5)

Я хочу заменить значения a1 - a5 на основе условий для каждой строки в фрейме данных. Условия:

Если main == 1, заменить a1 на 0

Если main == 2, заменить a2 на 0

Если main == 3, заменить a3 на 0

Если main == 4, заменить a4 на 0

Если main == 5, заменить a5 на 0

Но если значение изменяется в строке, другое не должно касаться и оставайся таким же. Результат должен выглядеть примерно так:

main a1 a2 a3 a4 a5
1    0  1  1  1  1
4    1  1  1  0  1
3    1  1  0  1  1
5    1  1  1  1  0
3    1  1  0  1  1
...

Я перепробовал несколько циклов с операторами if, но не могу заставить работать.

Может ли кто-нибудь мне помочь? Спасибо

Ответы [ 2 ]

2 голосов
/ 14 января 2020

Это можно сделать с помощью row/column индексации

df[-1][cbind(seq_len(nrow(df)), df$main)] <- 0
head(df)
#  main a1 a2 a3 a4 a5
#1    5  1  1  1  1  0
#2    1  0  1  1  1  1
#3    4  1  1  1  0  1
#4    4  1  1  1  0  1
#5    1  0  1  1  1  1
#6    2  1  0  1  1  1

Мы можем подстановить столбцы по нумерации c по индексу или по именам

nm1 <- paste0("a", 1:5)

или

nm1 <- names(df)[2:6]

Или

nm1 <- 2:6

df[nm1][cbind(seq_len(nrow(df)), df$main)] <- 0

Если нам нужен ifelse, то

df[nm1] <- lapply(1:5, function(i) ifelse(df$main == i,  0, df[[i + 1]]))
1 голос
/ 14 января 2020

Для замены inplace Вы можете сделать:

df[cbind(1:nrow(df), df$main + 1)] <- 0

head(df)
  main a1 a2 a3 a4 a5
1    4  1  1  1  0  1
2    5  1  1  1  1  0
3    2  1  0  1  1  1
4    1  0  1  1  1  1
5    4  1  1  1  0  1
6    3  1  1  0  1  1

для замены не inplace, вы можете сделать:

 replace(df, cbind(1:100, df$main + 1), 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...