2011-10-12 12 views
11

J'ai une trame de données avec 3 variables et 250K enregistrements. À titre d'exemple, considéronsComment échanger des valeurs entre 2 colonnes

> 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 

et que vous souhaitez échanger des valeurs entre V1 et V3 en fonction de la valeur de V2 comme suit: si V2 == 'b' puis V1 <- V3 et V3 <- V1 entraînant

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

J'ai essayé do boucle mais cela prend une éternité. Si j'utilise Perl, cela prend quelques secondes. Je crois que cette tâche peut également être accomplie efficacement dans R. Toutes les suggestions sont appréciées.

+0

Je suis curieux de savoir comment cette situation est survenue, si cela ne vous dérange pas. J'ai une certaine expérience de l'utilisation de logiciels au moins conçus pour travailler avec des données d'enquête, mais comme nous suivons la tendance de l'intégration avec les bases de données informatiques, les questions de structure de données ont commencé à se poser et j'ai dû commencer à réfléchir nous stockons des choses dans des tableaux. C'est pourquoi je suis curieux de savoir comment votre situation est apparue :) – Jonathan

Répondre

4

Édition J'ai été dérangé avec des noms de colonne, désolé. Cela marche.

Si cela ne vous dérange pas les lignes qui se terminent dans des ordres différents, cela est une sorte d'une façon « mignon » pour ce faire:

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) 

Fondamentalement, c'est juste saisir les lignes où V2 == 'b', renverse la colonnes et le refoule avec tout le reste. Cela peut être étendu si vous avez plus de colonnes qui n'ont pas besoin de changer; vous utiliseriez simplement un index entier avec ces valeurs transposées, plutôt que simplement 3:1.

+0

C'est une excellente façon de le faire! +1 – Chris

14

Essayez cette

> 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 
+0

solution soignée! +1 – TMS

10

Vous pouvez utiliser transform pour ce faire.

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

J'essaie x = read.table ("1.txt") x <- transformer (x, x [[1]] <- ifelse (x [[1]]> x [[2]], x [[2]], x [[1]]], x [[2]] <- ifelse (x [[1]]> x [[2]], x [[1]], x [[2] ])) mais sans succès! – phoenix

Questions connexes