วิธีใช้ฟังก์ชัน 'กวาด'


101

เมื่อฉันดูที่มาของแพ็คเกจ 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ว่าต้องใช้พารามิเตอร์หนึ่งมากขึ้นsweepSTATS

ความแตกต่างที่สำคัญอีกประการหนึ่งคือ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 ไม่ได้จำลองผลลัพธ์ของคุณ คุณตอบคำถามของคุณเอง
John

การใช้งานเพียงอย่างเดียวapplyที่ฉันสามารถหาได้สำหรับผลลัพธ์นี้เป็นสิ่งที่คล้ายt(apply(t(M), 2, "-", dx))กัน แต่มันค่อนข้างน่ารังเกียจ
Ken Williams

คำตอบ:


87

sweep()โดยทั่วไปจะใช้เมื่อคุณดำเนินการเมทริกซ์ตามแถวหรือตามคอลัมน์และอินพุตอื่น ๆ ของการดำเนินการคือค่าที่แตกต่างกันสำหรับแต่ละแถว / คอลัมน์ apply()ไม่ว่าคุณจะทำงานโดยแถวหรือคอลัมน์ที่ถูกกำหนดโดยอัตรากำไรขั้นต้นสำหรับ ค่าที่ใช้สำหรับสิ่งที่ฉันเรียกว่า "อินพุตอื่น" ถูกกำหนดโดย STATS ดังนั้นสำหรับแต่ละแถว (หรือคอลัมน์) คุณจะใช้ค่าจาก STATS และใช้ในการดำเนินการที่กำหนดโดย FUN

ตัวอย่างเช่นหากคุณต้องการเพิ่ม 1 ในแถวที่ 1, 2 ไปยังที่ 2 ฯลฯ ของเมทริกซ์ที่คุณกำหนดไว้คุณจะทำ:

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

ฉันไม่เข้าใจคำจำกัดความในเอกสาร R อย่างตรงไปตรงมาฉันเพิ่งเรียนรู้จากการค้นหาตัวอย่าง


2
เพื่อถอดความเล็กน้อย: STATSดูเหมือนจะเป็นป้ายกำกับที่ไม่ถูกต้องสำหรับตัวแปรนี้ เป็นอินพุตFUNที่ใช้เพื่อแก้ไขค่าของแต่ละองค์ประกอบในเมทริกซ์ ( Mในตัวอย่างนี้) STATSสามารถเป็นได้ทั้งค่าคงที่หรือรายการ / เวกเตอร์ / ฯลฯ MARGINที่มีขนาดตรงกับขนาดของการเลือก ฉันคิด.
Roland

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สามารถสันนิษฐานได้ว่าหมายถึง '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)

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.