Cách sử dụng chức năng 'quét'


100

Khi tôi xem nguồn của R Packages, tôi thấy chức năng sweepđược sử dụng khá thường xuyên. Đôi khi, nó được sử dụng khi một chức năng đơn giản hơn đã đủ (ví dụ apply:), những lần khác, không thể biết chính xác nó đang làm gì nếu không dành một lượng thời gian hợp lý để xem qua khối mã mà nó ở trong.

Thực tế là tôi có thể tái tạo sweephiệu ứng của bằng cách sử dụng một hàm đơn giản hơn cho thấy rằng tôi không hiểu sweepcác trường hợp sử dụng cốt lõi của nó, và thực tế là hàm này được sử dụng thường xuyên cho thấy rằng nó khá hữu ích.

Bối cảnh:

sweeplà một hàm trong thư viện chuẩn của R; đối số của nó là:

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

Như bạn có thể thấy, các đối số tương tự như applymặc dù sweepyêu cầu thêm một tham số STATS,.

Một điểm khác biệt chính khác là sweeptrả về một mảng có cùng hình dạng với mảng đầu vào, trong khi kết quả trả về applyphụ thuộc vào hàm được truyền vào.

sweep trong hành động:

# 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

Vì vậy, tóm lại, những gì tôi đang tìm kiếm là một hoặc hai trường hợp sử dụng mẫu cho sweep.

Vui lòng không đọc lại hoặc liên kết đến Tài liệu R, danh sách gửi thư hoặc bất kỳ nguồn nào trong số các nguồn R 'chính' - giả sử tôi đã đọc chúng. Điều tôi quan tâm là cách các lập trình viên / nhà phân tích R có kinh nghiệm sử dụng sweeptrong mã riêng của họ.


2
M-dx không sao chép kết quả của bạn. Bạn đã trả lời câu hỏi của riêng bạn.
John

Cách sử dụng duy nhất applymà tôi có thể tìm ra cho kết quả này là một cái gì đó giống như t(apply(t(M), 2, "-", dx)), nhưng điều đó khá khó chịu.
Ken Williams

Câu trả lời:


84

sweep()thường được sử dụng khi bạn vận hành ma trận theo hàng hoặc theo cột và đầu vào khác của thao tác là một giá trị khác cho mỗi hàng / cột. Cho dù bạn hoạt động theo hàng hay cột được xác định bởi MARGIN, như đối với apply(). Các giá trị được sử dụng cho cái mà tôi gọi là "đầu vào khác" được xác định bởi STATS. Vì vậy, đối với mỗi hàng (hoặc cột), bạn sẽ lấy một giá trị từ STATS và sử dụng trong hoạt động được xác định bởi FUN.

Ví dụ: nếu bạn muốn thêm 1 vào hàng thứ nhất, 2 vào hàng thứ 2, v.v. của ma trận bạn đã xác định, bạn sẽ thực hiện:

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

Thành thật mà nói, tôi cũng không hiểu định nghĩa trong tài liệu R, tôi chỉ học được bằng cách tra cứu các ví dụ.


2
để diễn giải một chút: STATScó vẻ là một nhãn xấu cho biến này. Nó là một đầu vào FUNđược sử dụng để sửa đổi giá trị của từng phần tử trong ma trận ( Mtrong ví dụ này). STATScó thể là một hằng số hoặc một danh sách / vectơ / vv có kích thước phù hợp với kích thước đã chọn MARGIN. Tôi nghĩ.
Roland

16

scan () có thể tuyệt vời để thao tác một cách có hệ thống một ma trận lớn theo từng cột hoặc từng hàng, như được hiển thị bên dưới:

> 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

Được, ví dụ này đơn giản, nhưng thay đổi đối số STATS và FUN, các thao tác khác có thể thực hiện được.


6

Câu hỏi này hơi cũ, nhưng vì gần đây tôi đã phải đối mặt với vấn đề này, một cách sử dụng quét điển hình có thể được tìm thấy trong mã nguồn cho hàm thống kê cov.wt, được sử dụng để tính toán ma trận hiệp phương sai có trọng số. Tôi đang xem mã trong R 3.0.1. Ở đây sweepđược sử dụng để trừ đi giá trị cột trước khi tính toán hiệp phương sai. Trên dòng 19 của mã, vectơ căn giữa có nguồn gốc:

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

và trên dòng 54, nó bị quét ra khỏi ma trận

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

Tác giả của mã đang sử dụng giá trị mặc định FUN = "-", điều này khiến tôi bối rối trong một thời gian.


3

Một cách sử dụng là khi bạn tính tổng trọng số cho một mảng. Trường hợp rowSumshoặc colSumscó thể được giả định là 'trọng số = 1', sweepcó thể được sử dụng trước đó để đưa ra kết quả có trọng số. Điều này đặc biệt hữu ích cho các mảng có> = 3 kích thước.

Điều này xuất hiện, ví dụ khi tính toán ma trận hiệp phương sai có trọng số theo ví dụ của @James King.

Đây là một dự án khác dựa trên một dự án hiện tại:

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

Bạn có thể sử dụng sweephàm để chia tỷ lệ và căn giữa dữ liệu như đoạn mã sau. Lưu ý rằng meanssdstùy ý ở đây (bạn có thể có một số giá trị tham chiếu mà bạn muốn chuẩn hóa dữ liệu dựa trên chúng):

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

Mã này chuyển đổi điểm thô thành điểm T (với trung bình = 50 và 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 như tôi đã đề cập trong câu trả lời, vì tôi có thể muốn chia tỷ lệ các mục theo giá trị trung bình và sd tham chiếu, không phải giá trị trung bình và sd của chính mẫu hiện tại. Nó xảy ra khi bạn xử lý các bài kiểm tra được quản lý và chuẩn hóa trong các mẫu lớn và bạn muốn chuẩn hóa điểm mẫu nhỏ của mình theo thống kê của chúng.
Ehsan88
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.