简体   繁体   中英

GNU R:Use sapply on sapply

I have a list of statuses. Each list element contains the status of a sensor for every minute of a day (1440 entries, 0 or 1). The list contains all sensors.

For example, statuses[[3]] gives a vector with 1440 entries, containing all the 0's and 1's of each minute.

The statuses of all sensors in, let's say, minute 800 is:

sapply(statuses,'[',800)

I'd like to get the number of active sensors (ie showing 1) per minute. How do I do that? Somehow one has to put another sapply() around this...

The solution using a for loop would look like this

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

It seems to me there are several ways to accomplish what you want; this is what jumped out at me first: Since the length of each element of the list is the same, you can treat it as a data frame and use apply. I illustrate this approach below using simulated data that I believe matches your description of your data (this would be for five observations of three sensors):

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

You can easily manually confirm this gives the result you want with this small example. Below you can see the speed benefit of this approach relative to the for loop approach or using sapply on sapply -- I created a larger sample (1440 observations each for three sensors) and used benchmark to see the speed differences:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM