2015-09-09 14 views
8

Ho un vettore c(9,6,3,4,2,1,5,7,8) e voglio passare gli elementi all'indice 2 e all'indice 5 nel vettore. Tuttavia, non voglio dover creare una variabile temporanea e vorrei fare lo switch in una sola chiamata. Come potrei farlo?Scambia due elementi di un vettore in una chiamata

risposta

9

È possibile utilizzare replace().

x <- c(9, 6, 3, 4, 2, 1, 5, 7, 8) 
replace(x, c(2, 5), x[c(5, 2)]) 
# [1] 9 2 3 4 6 1 5 7 8 

E se non vuoi nemmeno assegnare x, è possibile utilizzare

replace(
    c(9, 6, 3, 4, 2, 1, 5, 7, 8), 
    c(2, 5), 
    c(9, 6, 3, 4, 2, 1, 5, 7, 8)[c(5, 2)] 
) 
# [1] 9 2 3 4 6 1 5 7 8 

ma questo è un po 'sciocco. Probabilmente vorrai che venga assegnato x all'inizio.

+1

nota che 'replace' è solo un wrapper per' x [c (2, 5)] = x [c (5, 2)] '. – MichaelChirico

7

Che ne dici di solo x[c(i,j)] <- x[c(j,i)]? Simile a replace(...), ma forse un po 'più semplice.

swtch <- function(x,i,j) {x[c(i,j)] <- x[c(j,i)]; x} 
swtch(c(9,6,3,4,2,1,5,7,8) , 2,5) 
# [1] 9 2 3 4 6 1 5 7 8 
4

Se si desidera effettivamente farlo senza creare una copia temporanea del vettore, è necessario scrivere una breve funzione C.

library(inline) 
swap <- cfunction(c(i = "integer", j = "integer", vec="integer")," 
        int *v = INTEGER(vec); 
        int ii = INTEGER(i)[0]-1, jj = INTEGER(j)[0]-1; 
        int tmp = v[ii]; 
        v[ii] = v[jj]; 
        v[jj] = tmp; 
        return R_NilValue; 
        ") 

vec <- as.integer(c(9,6,3,4,2,1,5,7,8)) 
swap(2L, 5L, vec) 

vec 
# [1] 9 2 3 4 6 1 5 7 8 
Problemi correlati