代码之家  ›  专栏  ›  技术社区  ›  HnCetin

使用自定义函数时Lappy出现意外结果

  •  3
  • HnCetin  · 技术社区  · 7 年前

    假设我有三个数据,每个数据包含随机的20个数字:

    > dataone
     [1]  5.7 15.3 14.0 13.2 14.0  9.4 19.0 13.7 19.4 19.3 11.5 16.6 17.7  3.2  4.7  1.4 18.4 10.1  9.6 16.4
    > datatwo
     [1] 21 13 29 29 22 13 18 13 29 13 23 17 17 11 29 15 20 21 26 17
    > datathree
     [1]  6.7  9.8  1.9  5.9  5.3  5.2  1.2  5.3  2.2  8.6  2.9  4.6  4.9  6.1  9.4 10.0  5.1  9.8  3.1  3.2
    

    我想按顺序计算每四个数字的平均值。说清楚点,我想要 [1:4] , [5:8] , [9:12] 等等,对于每个数据。所以,我写了这个函数:

    foursmean <- function (x) {
      starts <- seq(1, 20, by = 4) 
      means <- numeric(length(starts))
      for (i in 1:length(starts)){
        a <- mean(x[starts[i]:(starts[i]+3)] )
        means[i] <- a  }
      print(means)
    }
    

    到目前为止,它运行得很好:

    > foursmean(dataone)
    [1] 12.1 14.0 16.7  6.7 13.6
    

    但是,我不想花时间对所有数据使用函数。因此,我将它们收集在一个列表中:

    dataall <- list(dataone, datatwo, datathree)
    

    然后我使用 lapply() 要在列表上运行函数,请执行以下操作:

    > lapply(dataall, foursmean)
    [1] 12.1 14.0 16.7  6.7 13.6
    [1] 23 16 21 18 21
    [1] 6.0 4.2 4.6 7.6 5.3
    [[1]]
    [1] 12.1 14.0 16.7  6.7 13.6
    
    [[2]]
    [1] 23 16 21 18 21
    
    [[3]]
    [1] 6.0 4.2 4.6 7.6 5.3
    

    我不明白为什么它会产生重复的结果。当我检查结构时,它说“ 5s清单中的3个清单 “。我想不出来,也解决不了。

    我只期待这一部分:

    [[1]]
    [1] 12.1 14.0 16.7  6.7 13.6
    
    [[2]]
    [1] 23 16 21 18 21
    
    [[3]]
    [1] 6.0 4.2 4.6 7.6 5.3
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Sathish    7 年前

    您必须删除 print 在你的代码中。

    也许你可以试试这种形式的功能。

    数据:

    dataone <-   c( 5.7, 15.3, 14.0, 13.2 ,14.0,  9.4 ,19.0 ,13.7, 19.4, 19.3 ,11.5, 16.6, 17.7,  3.2 , 4.7,  1.4, 18.4, 10.1,  9.6, 16.4 )
    datatwo <- c( 21, 13, 29 ,29 ,22 ,13 ,18 ,13 ,29 ,13, 23, 17 ,17 ,11, 29, 15, 20, 21 ,26, 17)
    datathree <- c( 6.7,  9.8 , 1.9,  5.9,  5.3,  5.2  ,1.2  ,5.3 , 2.2,  8.6 , 2.9,  4.6 , 4.9 , 6.1,  9.4, 10.0 , 5.1 , 9.8 , 3.1,  3.2)
    dataall <- list(dataone = dataone, 
                    datatwo = datatwo, 
                    datathree = datathree )
    

    代码:

    foursmean <- function (x, by ) {
      x <- split( x = x, f = ceiling( seq_along(x) / by) )
      sapply( x, mean, na.rm = TRUE )
    }
    

    输出: by 指定要拆分向量的大小。你可以有任何正数

    sapply(dataall, foursmean, by = 4)
    #   dataone datatwo datathree
    # 1  12.050    23.0     6.075
    # 2  14.025    16.5     4.250
    # 3  16.700    20.5     4.575
    # 4   6.750    18.0     7.600
    # 5  13.625    21.0     5.300
    
    sapply(dataall, foursmean, by = 5)
    #   dataone datatwo datathree
    # 1   12.44    22.8      5.92
    # 2   16.16    17.2      4.50
    # 3   10.74    19.4      5.58
    # 4   11.18    19.8      6.24