Как использовать функцию «развертки» - PullRequest
93 голосов
/ 10 августа 2010

Когда я смотрю на источник пакетов R, я вижу функцию sweep, используемую довольно часто. Иногда это используется, когда достаточно более простой функции (например, apply), в других случаях невозможно точно знать, что он делает без потратить немало времени, чтобы пройти через блок кода, в котором он находится.

Тот факт, что я могу воспроизвести эффект sweep, используя более простую функцию, предполагает, что я не понимаю основные случаи использования sweep, и тот факт, что эта функция используется так часто, говорит о том, что она весьма полезна.

Контекст:

sweep - функция в стандартной библиотеке R; его аргументы:

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

Как видите, аргументы аналогичны apply, хотя sweep требует еще один параметр, STATS.

Другое ключевое отличие состоит в том, что sweep возвращает массив той же формы , что и входной массив, тогда как результат, возвращаемый apply, зависит от переданной функции.

sweep в действии:

# 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

Итак, в общем, я ищу примерный вариант использования или два для sweep.

Пожалуйста, не читайте и не ссылайтесь на Документацию R, списки рассылки или любые «первичные» источники R - предположим, что я их прочитал. Что меня интересует, так это то, как опытные программисты / аналитики R используют sweep в своем собственном коде.

Ответы [ 5 ]

75 голосов
/ 03 мая 2011

sweep обычно используется, когда вы управляете матрицей по строкам или столбцам, а другой вход операции - это другое значение для каждой строки / столбца. Работаете ли вы по строке или столбцу, определяется MARGIN, как для применения. Значения, используемые для того, что я назвал «другим входом», определяются STATS. Таким образом, для каждой строки (или столбца) вы берете значение из STATS и используете его в операции, определенной FUN.

Например, если вы хотите добавить 1 к 1-й строке, 2 к 2-й и т. Д. Матрицы, которую вы определили, вы сделаете:

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

Я, честно говоря, тоже не понял определения в документации R, я только что узнал, посмотрев примеры.

16 голосов
/ 10 октября 2013

sweep () может быть полезен для систематического манипулирования большой матрицей столбец за столбцом или строка за строкой, как показано ниже:

> 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

Конечно, этот пример прост, но с изменением STATS иВесёлый аргумент, возможны другие манипуляции.

7 голосов
/ 26 января 2014

Этот вопрос немного устарел, но поскольку я недавно столкнулся с этой проблемой, типичное использование развертки можно найти в исходном коде для функции статистики cov.wt, используемой для вычисления взвешенных ковариационных матриц. Я смотрю на код в R 3.0.1. Здесь sweep используется для вычитания среднего значения столбца перед вычислением ковариации. В строке 19 кода получается центрирующий вектор:

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

и по строке 54 она выметается из матрицы

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

Автор кода использует значение по умолчанию FUN = "-", которое некоторое время меня смущало.

2 голосов
/ 11 августа 2015

Одно использование - это когда вы вычисляете взвешенные суммы для массива. Где rowSums или colSums могут означать 'weights = 1', sweep может использоваться до этого для получения взвешенного результата. Это особенно полезно для массивов с> = 3 размерами.

Это подходит, например, при расчете взвешенной ковариационной матрицы согласно примеру @James King.

Вот еще один, основанный на текущем проекте:

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)
1 голос
/ 23 сентября 2014

Вы можете использовать функцию sweep для масштабирования и центрирования данных, как показано в следующем коде.Обратите внимание, что means и sds здесь произвольны (у вас могут быть некоторые эталонные значения, которые вы хотите стандартизировать на основе данных):

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

Этот код преобразует необработанные оценки в T оценки (со средним= 50 и сд = 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...