【问题标题】:GNU R:Use sapply on sapplyGNU R:在 sapply 上使用 sapply
【发布时间】:2017-09-28 09:50:50
【问题描述】:

我有一个状态列表。每个列表元素包含一天中每一分钟的传感器状态(1440 个条目,0 或 1)。该列表包含所有传感器。

例如,statuses[[3]] 给出了一个包含 1440 个条目的向量,其中包含每分钟的所有 0 和 1。

假设第 800 分钟内所有传感器的状态为:

sapply(statuses,'[',800)

我想获取每分钟活动传感器的数量(即显示 1 个)。我怎么做?不知何故,必须在这个周围加上另一个 sapply()...

使用 for 循环的解决方案如下所示

status_ones <- rep(0,1440)
for (k in 1:1440){
  status_ones[k] <- sum(sapply(statuses,'[',k))
}

【问题讨论】:

    标签: r lapply sapply


    【解决方案1】:

    在我看来,有几种方法可以实现你想要的;这是我首先跳出来的:由于列表中每个元素的长度相同,因此您可以将其视为数据框并使用apply。我在下面使用我认为与您对数据的描述相匹配的模拟数据来说明这种方法(这将是对三个传感器的五次观察):

    set.seed(42)
    statuses <- lapply(1:3, function(x) sample(0:1, 5, replace=TRUE))
    statuses
    # [[1]]
    # [1] 1 1 0 1 1
    # 
    # [[2]]
    # [1] 1 1 0 1 1
    # 
    # [[3]]
    # [1] 0 1 1 0 0
    status_ones <- apply(as.data.frame(statuses), 1, sum)
    status_ones
    # [1] 2 3 1 2 2
    

    您可以通过这个小示例轻松手动确认这是否提供了您想要的结果。下面您可以看到这种方法相对于for 循环方法或在sapply 上使用sapply 的速度优势——我创建了一个更大的样本(三个传感器每个1440 次观察)并使用benchmark 来查看速度差异:

    library(rbenchmark)
    statuses <- lapply(1:3, function(x) sample(0:1, 1440, replace=TRUE))
    benchmark(apply=apply(as.data.frame(statuses), 1, sum),
              sapply=sapply(1:1440, function(x) sum(sapply(statuses, '[', x))),
              loop=for ( i in 1:1440 ) { sum(sapply(statuses, '[', i)) },
              columns=c('test', 'elapsed', 'relative', 'user.self'),
              order='relative')
        test elapsed relative user.self
    1  apply   0.883    1.000     0.660
    2 sapply   6.115    6.925     5.616
    3   loop   6.305    7.140     5.776
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      相关资源
      最近更新 更多