【问题标题】:How to perform multiple operations for each column in matrix in R without using FOR loops?如何在不使用 FOR 循环的情况下对 R 中矩阵中的每一列执行多项操作?
【发布时间】:2016-07-29 17:29:58
【问题描述】:

假设我在 R 工作区中有如下数据框

   a b c d
s  1 2 3 4
t  2 4 5 6
u  1 9 7 6
v  9 2 3 4
w  3 2 0 2
x  3 2 0 9
y  9 2 4 3
z  8 3 4 5

如何在不使用 R 中的 FOR LOOPS 的情况下自动提取矩阵每列的范围、平均值、标准差、中值、最大值和最小值?可以用apply/sapply/lapply吗??

【问题讨论】:

    标签: r for-loop lapply


    【解决方案1】:

    对于这种情况有几个不同的选项。其他人提到了apply 函数,但apply 在矩阵上工作,如果给定一个数据框,它将首先将其转换为矩阵,然后再应用该函数。对于示例数据框,这不是问题(但首先转换效率会很低),但如果与包含非数字列的数据框一起使用,则可能会导致问题。

    最好使用sapply,它直接作用于列表(数据框是列表的一种形式):

    > sapply(mtcars, function(x) c(mean(x), median(x), sd(x)))
               mpg      cyl     disp        hp      drat        wt      qsec
    [1,] 20.090625 6.187500 230.7219 146.68750 3.5965625 3.2172500 17.848750
    [2,] 19.200000 6.000000 196.3000 123.00000 3.6950000 3.3250000 17.710000
    [3,]  6.026948 1.785922 123.9387  68.56287 0.5346787 0.9784574  1.786943
                vs        am      gear   carb
    [1,] 0.4375000 0.4062500 3.6875000 2.8125
    [2,] 0.0000000 0.0000000 4.0000000 2.0000
    [3,] 0.5040161 0.4989909 0.7378041 1.6152
    

    您可以通过更改上面的函数来计算每列所需的任何函数。

    您可能还想考虑 dplyr 包,它具有执行此类操作的功能,其形式可能更具可读性,并且可以以更简单的方式适应更复杂的情况。

    > library(dplyr)
    > mtcars %>% summarise_each(funs(mean,median,sd))
      mpg_mean cyl_mean disp_mean  hp_mean drat_mean wt_mean qsec_mean vs_mean
    1 20.09062   6.1875  230.7219 146.6875  3.596563 3.21725  17.84875  0.4375
      am_mean gear_mean carb_mean mpg_median cyl_median disp_median hp_median
    1 0.40625    3.6875    2.8125       19.2          6       196.3       123
      drat_median wt_median qsec_median vs_median am_median gear_median
    1       3.695     3.325       17.71         0         0           4
      carb_median   mpg_sd   cyl_sd  disp_sd    hp_sd   drat_sd     wt_sd
    1           2 6.026948 1.785922 123.9387 68.56287 0.5346787 0.9784574
       qsec_sd     vs_sd     am_sd   gear_sd carb_sd
    1 1.786943 0.5040161 0.4989909 0.7378041  1.6152
    
    > mtcars %>% summarise_each(funs(mean,median,sd)) %>% 
      matrix(nrow=ncol(mtcars), dimnames=list(names(mtcars), c('Mean','Median','SD')))
         Mean     Median SD       
    mpg  20.09062 19.2   6.026948 
    cyl  6.1875   6      1.785922 
    disp 230.7219 196.3  123.9387 
    hp   146.6875 123    68.56287 
    drat 3.596563 3.695  0.5346787
    wt   3.21725  3.325  0.9784574
    qsec 17.84875 17.71  1.786943 
    vs   0.4375   0      0.5040161
    am   0.40625  0      0.4989909
    gear 3.6875   4      0.7378041
    carb 2.8125   2      1.6152   
    

    【讨论】:

      【解决方案2】:
      apply(df, 2, summary)
                 a    b    c     d
      #Min.    1.00 2.00 0.00 2.000
      #1st Qu. 1.75 2.00 2.25 3.750
      #Median  3.00 2.00 3.50 4.500
      #Mean    4.50 3.25 3.25 4.875
      #3rd Qu. 8.25 3.25 4.25 6.000
      #Max.    9.00 9.00 7.00 9.000
      

      【讨论】:

      • sapply(df, summary)。要获取范围,请使用sapply(df, range)
      • 很好,我不知道sapply 这样做了:)
      • 或者只是摘要(df)。摘要将应用于所有列。
      • summary 函数只是一个示例,以便向 OP 展示如何遍历列
      【解决方案3】:
      fun <- c('mean', 'sd', 'median', 'min', 'max')
      sapply(fun, function(x) apply(dff, 2, match.fun(x)))
      

      你会得到这样的输出,

         mean       sd median min max
      a 4.500 3.545621    3.0   1   9
      b 3.250 2.434866    2.0   2   9
      c 3.250 2.375470    3.5   0   7
      d 4.875 2.167124    4.5   2   9
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-16
        • 2020-05-12
        • 1970-01-01
        • 2015-06-23
        • 2021-12-31
        • 1970-01-01
        • 2014-05-01
        • 2020-04-11
        相关资源
        最近更新 更多