Как поменять значения между двумя столбцами - PullRequest
12 голосов
/ 13 октября 2011

У меня есть фрейм данных с тремя переменными и 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. Любые предложения приветствуются.

Ответы [ 3 ]

17 голосов
/ 13 октября 2011

Попробуйте это

 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
13 голосов
/ 13 октября 2011

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

df <- transform(df, V3 = ifelse(V2 == 'b', V1, V3), V1 = ifelse(V2 == 'b', V3, V1))
4 голосов
/ 13 октября 2011

Отредактировано Меня запутали названия столбцов, извините. Это работает.

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

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...