2017-09-28 69 views
0

我有一個狀態列表。每個列表元素包含一天中每一分鐘的傳感器狀態(1440個條目,0或1)。該列表包含所有傳感器。GNU R:在sapply上使用sapply

例如,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)) 
} 

回答

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環方法或使用sapplysapply這種方法的速度益處 - 我創建更大的樣本(每個用於三個傳感器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