首页 文章

如何使用'sweep'功能

提问于
浏览
81

当我查看R Packages的源代码时,我看到函数 sweep 经常使用 . 有时候,当一个更简单的函数已经足够时(例如, apply ),它会被使用,有时它会在没有花费相当多的时间来逐步完成它所在的代码块的情况下使用它 .

事实上,我可以重现 sweep 's effect using a simpler function suggests that i don' t了解 sweep 's core use cases, and the fact that this function is used so often suggests that it' s非常有用 .

上下文:

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文档,邮件列表或任何'primary' R来源 - 假设我感兴趣的是有经验的R程序员/分析师如何在他们自己的代码中使用 sweep .

5 回答

  • 64

    一种用途是在计算数组的加权和时 . 如果 rowSumscolSums 可以假设为'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)
    
  • 15

    您可以使用 sweep 函数来缩放和居中数据,如下面的代码所示 . 请注意, 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
    
  • 1

    sweep 通常在按行或按列操作矩阵时使用,而操作的另一个输入对于每个行/列都是不同的值 . 无论是按行还是按列操作,都由MARGIN定义,与申请相同 . 用于我所谓的"the other input"的值由STATS定义 . 因此,对于每一行(或列),您将从STATS获取一个值并在FUN定义的操作中使用 .

    例如,如果要将1添加到您定义的矩阵的第1行,2到2,等等,您将执行以下操作:

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

    我坦率地不理解R文档中的定义,我只是通过查找示例来学习 .

  • 7

    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

    这个问题有点陈旧,但由于我最近遇到了这个问题,因此可以在统计函数 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 = "-" ,这让我困惑了一段时间 .

相关问题