Як користуватися функцією 'sweep'


100

Коли я дивлюся на джерело пакетів 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у власному коді.


2
M-dx не повторює ваш результат. Ви відповіли на власне запитання.
Джон

Єдине використання, applyяке я можу зрозуміти для цього результату, - це щось на зразок t(apply(t(M), 2, "-", dx)), але це досить неприємно.
Кен Вільямс

Відповіді:


84

sweep()зазвичай використовується, коли ви керуєте матрицею за рядком або стовпцем, а інший вхід операції є різним значенням для кожного рядка / стовпця. Чи працює ви за рядком або стовпцем, визначено MARGIN, як і дляapply() . Значення, використовувані для того, що я назвав "інший вхід", визначається STATS. Отже, для кожного рядка (або стовпця) ви будете приймати значення з STATS та використовувати в операції, визначеній FUN.

Наприклад, якщо ви хочете додати 1 до 1-го рядка, 2 до 2-го і т.д. матриці, яку ви визначили, ви зробите:

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

Я відверто не розумів визначення в документації на R, я просто дізнався, шукаючи приклади.


2
Якщо перефразувати трохи: STATSздається, це погана мітка для цієї змінної. Це вхід до FUNцього звикає змінювати значення кожного елемента в матриці ( M, у цьому прикладі). STATSможе бути константою або списком / вектором / тощо розміру, що відповідає розміру обраного MARGIN. Я думаю.
Роланд

16

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 і FUN, можливі інші маніпуляції.


6

Це питання трохи старе, але оскільки я нещодавно зіткнувся з цією проблемою, типове використання розгортки можна знайти у вихідному коді функції статистики 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 = "-", яке мене на деякий час бентежило.


3

Одне використання - це коли ви обчислюєте зважені суми для масиву. Де rowSumsабо colSumsможна вважати, що означає "ваги = 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)

0

Ви можете використовувати 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 та 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
@BenBolker, як я вже згадував у відповіді, тому що я, можливо, захочу масштабувати елементи відповідно до середнього значення та sd, а не середнього та sd самого поточного зразка. Це відбувається, коли ви маєте справу з тестами, які вводяться та стандартизуються у великих зразках, і ви хочете стандартизувати свій невеликий бал вибірки відповідно до їх статистики.
Ehsan88
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.