如何使用Rfunction“扫描”

当我看R软件包的来源时,我看到经常使用的函数扫描 。 有时使用简单的函数就足够了(比如“应用”),而在其他时候,如果不花费相当多的时间来遍历代码块,就不可能确切地知道它在做什么。

事实上,我可以使用更简单的函数来重现扫描的效果,这表明我不了解扫描的核心用例,而且这个函数经常使用的事实表明它非常有用。

上下文:

扫描是R标准库中的一个function; 它的方法签名是:

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'返回一个与input数组相同形状的数组,而'apply'返回的结果取决于传入的函数。

扫地行动:

 # eg, 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 

所以总而言之,我要找的是一个典型的用例或两个用于扫描

请不要背诵或链接到R文档,邮件列表或任何“主”R来源 – 假设我已经阅读过。 我感兴趣的是有经验的R程序员/分析师如何使用自己的代码进行扫描

通常在按行或按列操作matrix时使用sweep ,而对于每个行/列,操作的另一个input是不同的值。 无论您是按行还是按列操作,都由MARGIN定义,适用。 我称之为“其他input”的值是由STATS定义的。 因此,对于每行(或列),您将从STATS中获取一个值,并在FUN所定义的操作中使用。

例如,如果你想为你定义的matrix的第一行,第二行等添加1,你可以这样做:

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

我坦率地不明白R文档中的定义,我只是通过查找例子来学习。

sweep()可以很好地用于系统地逐列或逐行地处理大型matrix,如下所示:

 > 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参数,其他操作是可能的。

这个问题有点老,但是由于我最近面临这个问题,典型的扫描使用可以在stats函数cov.wt的源代码中cov.wt ,用于计算加权协方差matrix。 我在看R 3.0.1中的代码。 在计算协方差之前, sweep用于减去列平均值。 在代码的第19行中,导出了定心vector:

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

在第54行,它被扫出matrix

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

代码的作者使用默认值FUN = "-" ,这让我困惑了一会儿。

您可以使用sweepfunction来缩放和居中数据,如下面的代码。 请注意, meanssds在这里是任意的(你可能有一些参考值,你想基于它们来标准化数据):

 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 

一种用法是当你计算一个数组的加权和时。 如果rowSumscolSums可以被认为是“权重= 1”,那么可以在此之前使用sweep来给出加权结果。 这对于具有> = 3维的数组特别有用。

例如,当根据@James King的例子计算加权协方差matrix时,就会出现这种情况。

这是另一个基于当前项目的:

 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)