Como usar a função 'varredura'


100

Quando eu olho para a origem dos Pacotes R, vejo a função sweepusada com bastante frequência. Às vezes, é usado quando uma função mais simples seria suficiente (por exemplo, apply), outras vezes, é impossível saber exatamente o que está fazendo sem gastar um bom tempo para percorrer o bloco de código em que está.

O fato de eu poder reproduzir sweepo efeito de usando uma função mais simples sugere que não entendo sweepos principais casos de uso de, e o fato de que essa função é usada com tanta frequência sugere que é bastante útil.

O contexto:

sweepé uma função na biblioteca padrão de R; seus argumentos são:

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 você pode ver, os argumentos são semelhantes a applyembora sweeprequer mais um parâmetro STATS,.

Outra diferença importante é que sweepretorna um array da mesma forma que o array de entrada, enquanto o resultado retornado por applydepende da função passada.

sweep em ação:

# 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

Resumindo, o que estou procurando é um ou dois casos de uso exemplares sweep.

Por favor, não recite ou crie links para a Documentação R, listas de discussão ou qualquer uma das fontes 'primárias' de R - suponha que eu as li. Estou interessado em como programadores / analistas experientes em R usam sweepem seu próprio código.


2
M-dx não replica seu resultado. você respondeu sua própria pergunta.
— John

O único uso applyque posso descobrir para este resultado é algo como t(apply(t(M), 2, "-", dx)), mas isso é muito desagradável.
— Ken Williams

Respostas:


84

sweep()é normalmente usado quando você opera uma matriz por linha ou coluna, e a outra entrada da operação é um valor diferente para cada linha / coluna. Se você opera por linha ou coluna é definido por MARGIN, assim como por apply(). Os valores usados ​​para o que chamei de "a outra entrada" são definidos por STATS. Assim, para cada linha (ou coluna), você pegará um valor de STATS e usará na operação definida por FUN.

Por exemplo, se você quiser adicionar 1 à 1ª linha, 2 à 2ª, etc. da matriz que definiu, você fará:

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

Francamente, também não entendi a definição na documentação do R, apenas aprendi procurando exemplos.


2
parafraseando um pouco: STATSparece ser um rótulo ruim para essa variável. É uma entrada FUNque é usada para modificar o valor de cada elemento da matriz ( Mneste exemplo). STATSpode ser uma constante ou uma lista / vetor / etc de um tamanho correspondente ao tamanho do escolhido MARGIN. Eu acho que.
— Roland

16

sweep () pode ser ótimo para manipular sistematicamente uma grande matriz coluna por coluna ou linha por linha, conforme mostrado abaixo:

> 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

Concedido, este exemplo é simples, mas alterando o argumento STATS e FUN, outras manipulações são possíveis.


6

Esta questão é um pouco antiga, mas como recentemente enfrentei esse problema, um uso típico de varredura pode ser encontrado no código-fonte da função de estatísticas cov.wt, usada para calcular matrizes de covariância ponderada. Estou olhando o código em R 3.0.1. Aqui sweepé usado para subtrair as médias das colunas antes de calcular a covariância. Na linha 19 do código, o vetor de centralização é derivado:

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

e na linha 54 é varrido para fora da matriz

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

O autor do código está usando o valor padrão FUN = "-", o que me confundiu por um tempo.


3

Um uso é quando você está computando somas ponderadas para um array. Onde rowSumsou colSumspode ser assumido como significando 'pesos = 1', sweeppode ser usado antes disso para fornecer um resultado ponderado. Isso é particularmente útil para arrays com> = 3 dimensões.

Isso surge, por exemplo, ao calcular uma matriz de covariância ponderada conforme o exemplo de @James King.

Aqui está outro baseado em um projeto atual:

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)

0

Você pode usar a sweepfunção para dimensionar e centralizar dados como o código a seguir. Observe que meanse sdssão arbitrários aqui (você pode ter alguns valores de referência que deseja padronizar os dados com base neles):

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 converte pontuações brutas em pontuações T (com média = 50 e dp = 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
@BenBolker como mencionei na resposta, porque posso querer dimensionar os itens de acordo com uma média de referência e dp, não a média e dp da própria amostra atual. Isso ocorre quando você lida com testes que são administrados e padronizados em grandes amostras e deseja padronizar a pontuação de sua pequena amostra de acordo com suas estatísticas.
— Ehsan88
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.