Как поменять значения между двумя столбцами

У меня есть фрейм данных с тремя переменными и 250K записей. В качестве примера рассмотрим

df <- data.frame(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1))
V1 V2 V3
1  a  2
2  a  3
4  b  1

и хотите поменять значения между V1 и V3 на основе значения V2 следующим образом: если V2 == 'b' то V1 <- V3 и V3 <- V1 приводит к

V1 V2 V3
1  a  2
2  a  3
1  b  4

Я попытался сделать цикл, но это занимает вечность. Если я использую Perl, это займет несколько секунд. Я считаю, что эта задача может быть эффективно выполнена и в R. Любые предложения приветствуются.

Ответ 1

Попробуй это

 df <- data.frame(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1))
 df[df$V2 == "b", c("V1", "V3")] <- df[df$V2 == "b", c("V3", "V1")] 

который дает:

> df
  V1 V2 V3
1  1  a  2
2  2  a  3
3  1  b  4

Ответ 2

Вы можете использовать transform для этого.

df <- transform(df, V3 = ifelse(V2 == 'b', V1, V3), V1 = ifelse(V2 == 'b', V3, V1))

Ответ 3

Изменил меня, сокрушился с именами столбцов, извините. Это работает.

Если вы не возражаете, чтобы строки заканчивались в разных порядках, это вроде бы "милый" способ сделать это:

dat <- read.table(textConnection("V1 V2 V3
1  a  2
2  a  3
4  b  1"),sep = "",header = TRUE)

tmp <- dat[dat$V2 == 'b',3:1]
colnames(tmp) <- colnames(dat)
rbind(dat[dat$V2 != 'b',],tmp)

В принципе, это просто захват строк, где V2 == 'b', отменяет столбцы и шлепает обратно вместе со всем остальным. Это может быть расширено, если у вас больше столбцов, которые не требуют переключения; вы просто используете целочисленный индекс с этими значениями, а не только 3:1.