当我查看R Packages的源代码时,我看到函数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
返回的结果取决于传入的函数。< / p>
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
。
答案 0 :(得分:75)
sweep
通常在按行或按列操作矩阵时使用,而操作的其他输入对于每个行/列都是不同的值。无论是按行还是列操作,都由MARGIN定义,如同申请。用于我称之为“其他输入”的值由STATS定义。
因此,对于每一行(或列),您将从STATS获取一个值并在FUN定义的操作中使用。
例如,如果你想在你定义的矩阵的第1行,第2行,第2行等中添加1,你将会这样做:
sweep (M, 1, c (1: 4), "+")
我坦率地不理解R文档中的定义,我只是通过查看示例来学习。
答案 1 :(得分:15)
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参数,其他操作也是可能的。
答案 2 :(得分:7)
这个问题有点陈旧,但由于我最近遇到了这个问题,因此可以在统计函数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 :(得分:2)
一种用途是在计算数组的加权总和时。如果colSums
或sweep
可以假设为'权重= 1',则可以在此之前使用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)
来给出加权结果。这对于具有&gt; = 3维度的数组特别有用。
出现这种情况,例如根据@James King的例子计算加权协方差矩阵时。
这是基于当前项目的另一个:
{{1}}
答案 4 :(得分:1)
您可以使用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