2016-04-25 65 views
10

Mi è venuta meno la traduzione di this question in una soluzione data.table. (per semplificare userò lo stesso set di dati)
Quando V2 == "b Voglio scambiare le colonne tra V1 <-> V3.Scambio di valori tra due colonne utilizzando data.table

dt <- data.table(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1)) 
#V1 V2 V3 
#1: 1 a 2 
#2: 2 a 3 
#3: 4 b 1 

Il codice sotto sarebbe la soluzione di lavoro per data.frame, tuttavia a causa della quantità di frustrazione questo mi ha dato perché Io sto usando un data.table senza rendersi conto ora sono determinato a trovare una soluzione per data.table .

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

Ho provato a scrivere una funzione lapply scorrendo il mio obiettivo lista scambio, hanno cercato di circoscrivere il problema di sostituire solo un valore, è tentato di chiamare i nomi delle colonne in modi diversi, ma tutti senza successo.
Questo è stato il tentativo più vicino sono riuscito a ottenere:

> dt[dt$V2 == "b", c("V1", "V3")] <- dt[dt$V2 == "b", c(V3, V1)] 
#Warning messages: 
#1: In `[<-.data.table`(`*tmp*`, dt$V2 == "b", c("V1", "V3"), value = c(1, : 
# Supplied 2 items to be assigned to 1 items of column 'V1' (1 unused) 
#2: In `[<-.data.table`(`*tmp*`, dt$V2 == "b", c("V1", "V3"), value = c(1, : 
# Supplied 2 items to be assigned to 1 items of column 'V3' (1 unused) 

Come possiamo ottenere la soluzione data.table?

risposta

8

Possiamo provare

dt[V2=="b", c("V3", "V1") := .(V1, V3)] 
+0

Credo che usando '.SD' è più veloce di passare' lista (V1, V3) '? – BenBarnes

+1

@BenBarnes Non ho provato se sarà più veloce, sembra 'lista (V1, V3)' andrebbe bene anche. – akrun

+0

@eddi, cosa hai contro '.SDcols'? Penso che sia una soluzione più robusta nel caso tu abbia un vettore di colonne predefinite. –

2

Solo per divertimento. La soluzione di @akruns è chiaramente superiore. Ho pensato che avrei potuto creare una copia temporanea, effettuare l'inversione condizionale, e quindi eliminare la copia tutte utilizzando [.data.table operazioni in sequenza:

dt[, tv1 := V1][V2=="b", V1 := V3][V2=="b", V3 := tv1][ , tv1 := NULL] 

> dt 
    V1 V2 V3 
1: 1 a 2 
2: 2 a 3 
3: 1 b 4 
+0

Scambia i valori errati! Sembra bello! – Bas

+5

Ah, sì, stavo scambiando i valori "a" invece dei valori "b". Sembra che non valga la pena di essere riparato dal momento che sarà così lento. L'ho postato solo così le persone potevano buttare i pomodori. –

+0

almeno fai una soluzione 'bitwXor' se stai mirando a divertirti; non è divertito così com'è – eddi

Problemi correlati