Pregunta Cómo usar la función 'barrido'


Cuando miro la fuente de los R Paquetes, veo la función sweep usado bastante a menudo A veces se usa cuando una función más simple hubiera sido suficiente (por ejemplo, apply), otras veces, es imposible saber exactamente qué está haciendo sin pasando una buena cantidad de tiempo para pasar por el bloque de código en el que se encuentra.

El hecho de que puedo reproducir sweepEl efecto de usar una función más simple sugiere que No entiendo sweepcasos de uso de núcleo, y el hecho de que esta función se utiliza tan a menudo sugiere que es bastante útil.

El contexto:

sweep es una función en la biblioteca estándar de R; sus argumentos son:

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 puede ver, los argumentos son similares a apply aunque sweep requiere un parámetro más, STATS.

Otra diferencia clave es que sweep devuelve una matriz de Misma forma como la matriz de entrada, mientras que el resultado devuelto por apply depende de la función pasada.

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

En resumen, lo que estoy buscando es un caso de uso ejemplar o dos para sweep.

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


75
2017-08-09 23:15


origen


Respuestas:


sweep normalmente se usa 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 quiere agregar 1 a la 1ra fila, 2 a 2, etc. de la matriz que definió, hará:

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

Francamente, no entendí la definición en la documentación de R, acabo de aprender buscando ejemplos.


59
2018-05-03 17:52



sweep () puede ser ideal para manipular sistemáticamente una matriz grande 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 el argumento STATS y FUN, otras manipulaciones son posibles.


15
2017-10-10 17:35



Esta pregunta es un poco vieja, pero dado que recientemente me he enfrentado a 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, utilizado para calcular matrices de covarianza ponderadas. Estoy mirando el código en R 3.0.1. aquí sweep se usa para restar medios de columna antes de calcular la covarianza. En la línea 19 del código se deriva el vector de centrado:

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

y en la línea 54 es barrido de la matriz

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

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


7
2018-01-26 01:19



Un uso es cuando estás computando ponderado sumas para una matriz. Dónde rowSums o colSums se puede suponer que significa 'pesos = 1', sweep se puede usar 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)

2
2017-08-11 19:33



Podrías usar sweep función para escalar y centrar datos como el siguiente código. Tenga en cuenta que means y sds aquí son arbitrarios (es posible que tenga algunos valores de referencia que desee estandarizar en función de 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 convierte puntajes brutos en puntajes T (con media = 50 y sd = 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

1
2017-09-22 22:19