2010-08-09 23 views
68

Cuando miro la fuente de R Paquetes, veo la función barrido utilizada con bastante frecuencia. A veces se utiliza cuando una función más simple hubiera bastado (por ejemplo, 'aplicar'), otras veces, es imposible saber exactamente lo que está haciendo sin pasando una buena cantidad de tiempo para pasar por el bloque de código.Cómo utilizar la función R 'Barrido'

el hecho de que puedo reproducir el efecto de barrido usando una función más simple sugiere que no entiendo los casos de uso del núcleo de barrido, y el hecho de que esta función se usa con tanta frecuencia sugiere que es bastante útil.

El contexto:

barrido es una función en la biblioteca estándar de R; es firma del método es:

sweep(x, MARGIN, STATS, FUN="-", check.margin=T, ...) 

# x is the data 
# STATS refers to the summary statistics which you wish to 'sweep out' 
# FUN is the function used to carry out the sweep, "-" is the default 

Como se puede ver, la firma del método es similar a 'aplicar' a pesar de 'barrido' requiere un parámetro más, de alta ''.

Otra diferencia clave es que 'barrido' devuelve una matriz de la misma forma como la matriz de entrada, mientras que el resultado devuelto por 'aplicar' depende de la función se ha pasado.

Sweep en acción :

# e.g., use 'sweep' to express a given matrix in terms of distance from 
# the respective column mean 

# create some data: 
M = matrix(1:12, ncol=3) 

# calculate column-wise mean for M 
dx = colMeans(M) 

# now 'sweep' that summary statistic from M 
sweep(M, 2, dx, FUN="-") 

    [,1] [,2] [,3] 
[1,] -1.5 -1.5 -1.5 
[2,] -0.5 -0.5 -0.5 
[3,] 0.5 0.5 0.5 
[4,] 1.5 1.5 1.5 

Así pues, en suma, lo que estoy buscando es un caso de uso ejemplar o dos para barrer .

No recite ni vincule a la documentación de R, a las listas de correo ni a ninguna de las fuentes "principales" de R, suponiendo que las he leído. Lo que me interesa es cómo los programadores/analistas R experimentados usan barrido en su propio código.

+2

M-DX no se replica su resultado. Ha respondido a su propia pregunta. – John

+0

El único uso de 'aplicar' que puedo deducir para este resultado es algo como' t (aplicar (t (M), 2, "-", dx)) ', pero eso es bastante desagradable. –

Respuesta

56

sweep se usa normalmente cuando se opera una matriz por fila o por columna, y la otra entrada de la operación tiene un valor diferente para cada fila/columna. Si usted opera por fila o columna está definido por MARGIN, como para aplicar. Los valores utilizados para lo que llamé "la otra entrada" están definidos por STATS. Por lo tanto, para cada fila (o columna), tomará un valor de STATS y lo usará en la operación definida por FUN.

Por ejemplo, si desea agregar 1 a la primera fila, 2 al segundo, etc ... de la matriz que ha definido, que va a hacer:

sweep (M, 1, c (1: 4), "+") 

francamente no habían entendido la definición en la documentación R, acabo de aprender buscando ejemplos.

+0

para parafrasear un poco: 'STATS' parece ser una etiqueta incorrecta para esta variable. Es una entrada a 'FUN' que se usa para modificar el valor de cada elemento en la matriz (' M', en este ejemplo). 'STATS' puede ser una constante o una lista/vector/etc. de un tamaño que coincida con el tamaño del' MARGEN' elegido. Creo. – Roland

14

barrido() puede ser grande para manipular sistemáticamente una matriz grande ya sea columna por columna, o fila por fila, como se muestra a continuación:

> print(size) 
    Weight Waist Height 
[1,] 130 26 140 
[2,] 110 24 155 
[3,] 118 25 142 
[4,] 112 25 175 
[5,] 128 26 170 

> sweep(size, 2, c(10, 20, 30), "+") 
    Weight Waist Height 
[1,] 140 46 170 
[2,] 120 44 185 
[3,] 128 45 172 
[4,] 122 45 205 
[5,] 138 46 200 

Por supuesto, este ejemplo es simple, pero cambiando las estadísticas y FUN argumento, otras manipulaciones son posibles.

6

Esta pregunta es un poco antigua, pero como he enfrentado recientemente este problema, se puede encontrar un uso típico del barrido en el código fuente de la función de estadísticas cov.wt, que se usa para calcular matrices de covarianza ponderadas. Estoy mirando el código en R 3.0.1. Aquí sweep se usa para restar los medios de columna antes de calcular la covarianza. En la línea 19 del código del vector de centrado se deriva:

center <- if (center) 
     colSums(wt * x) 
    else 0 

y en la línea 54 se hace circular fuera de la matriz

x <- sqrt(wt) * sweep(x, 2, center, check.margin = FALSE) 

El autor del código está utilizando el valor predeterminado FUN = "-", que me confundió por un tiempo.

1

Puede usar la función sweep para escalar y centrar datos como el siguiente código. Tenga en cuenta que means y sds son arbitrarias aquí (es posible que tenga algunos valores de referencia que desea estandarizar los datos basados ​​en ellos):

df=matrix(sample.int(150, size = 100, replace = FALSE),5,5) 

df_means=t(apply(df,2,mean)) 
df_sds=t(apply(df,2,sd)) 

df_T=sweep(sweep(df,2,df_means,"-"),2,df_sds,"/")*10+50 

Este código se convierten puntuaciones directas a puntuaciones T (con media = 50 y de = 10):

> df 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 109 8 89 69 15 
[2,] 85 13 25 150 26 
[3,] 30 79 48 1 125 
[4,] 56 74 23 140 100 
[5,] 136 110 112 12 43 
> df_T 
     [,1]  [,2]  [,3]  [,4]  [,5] 
[1,] 56.15561 39.03218 57.46965 49.22319 40.28305 
[2,] 50.42946 40.15594 41.31905 60.87539 42.56695 
[3,] 37.30704 54.98946 47.12317 39.44109 63.12203 
[4,] 43.51037 53.86571 40.81435 59.43685 57.93136 
[5,] 62.59752 61.95672 63.27377 41.02349 46.09661 
+0

si vas a escalar y centrar por qué no usas 'scale()' ... ??? –

+1

@BenBolker como mencioné en la respuesta, porque es posible que desee escalar los elementos de acuerdo con una media de referencia y sd, no la media y sd de la muestra actual en sí. Ocurre cuando se trata de pruebas que se administran y estandarizan en muestras grandes, y desea estandarizar su puntuación de muestra pequeña de acuerdo con sus estadísticas. – ehsan88

1

un uso es cuando se está calculando ponderados sumas de una matriz. Cuando se puede suponer que rowSums o colSums significan "pesos = 1", se puede usar sweep antes de esto para obtener un resultado ponderado. Esto es particularmente útil para matrices con> = 3 dimensiones.

Esto viene, p. al calcular una matriz de covarianza ponderada según el ejemplo de @James King.

Aquí hay otro basado en un proyecto actual:

set.seed(1) 
## 2x2x2 array 
a1 <- array(as.integer(rnorm(8, 10, 5)), dim=c(2, 2, 2)) 
## 'element-wise' sum of matrices 
## weights = 1 
rowSums(a1, dims=2) 
## weights 
w1 <- c(3, 4) 
## a1[, , 1] * 3; a1[, , 2] * 4 
a1 <- sweep(a1, MARGIN=3, STATS=w1, FUN="*") 
rowSums(a1, dims=2) 
Cuestiones relacionadas