Vectorizing for循环:访问以前的data.frame

时间:2016-05-09 22:58:00

标签: r

我正在尝试将循环转换为矢量化。在我的应用程序中,我有超过200万行,循环太慢。我已阅读此帖非常有用:Speed up the loop operation in R

以下是我的数据的示例:

m <- data.frame(time = 1:10, level = c(0,0,60,100,0,0,100,100,0,0))

>m
    time level
1     1     0
2     2     0
3     3    60
4     4   100
5     5     0
6     6     0
7     7   100
8     8   100
9     9     0
10   10     0

我想要的是一个列machine,它是&#34; on&#34;或者&#34;关闭&#34;取决于水平。

如果等级!= 0则机器=&#34;在&#34;

如果等级变为0,那么machine将在任意时段lag之后关闭。在此示例中,请说lag = 2,然后结果为:

    time level machine
1     1     0     off
2     2     0     off
3     3    60      on
4     4   100      on
5     5     0      on
6     6     0     off
7     7   100      on
8     8   100      on
9     9     0      on
10    10    0     off

有关如何对此操作进行矢量化的任何建议吗?我已经考虑过使用dplyr中的lag,但还没有找到办法让它发挥作用。

我已经编写了一个适用于此示例的循环,作为示例。

m$machine <- ifelse(m$level!=0, "on", 0)

tlag <- 2
# check to see if timeout period has elapsed
for (i in seq_along(m$machine)){
    if(m$machine[i]!="on") {
        nback <- i - tout
        if (nback <=0 ) nback <- 1
        if (sum(m$level[nback:i]) == 0){ #light should be off
            m$machine[i] <- "off"
        }
    }
}

for (i in seq_along(m$machine)){
    if(m$machine[i]==0) m$machine[i] <- "on"   
}

2 个答案:

答案 0 :(得分:2)

以下是使用dplyr软件包lag运营商的一种解决方案:

library(dplyr)
m %>% mutate(machine = ifelse((level != 0 |
                               (level == 0 &
                                lag(level, 1, default = 0) != 0)),
                              'on', 'off'))

输出如下:

   time level machine
1     1     0     off
2     2     0     off
3     3    60      on
4     4   100      on
5     5     0      on
6     6     0     off
7     7   100      on
8     8   100      on
9     9     0      on
10   10     0     off

答案 1 :(得分:2)

您可以使用data.table:

执行此操作
library(data.table)
m <- data.table(time = 1:10, level = c(0,0,60,100,0,0,100,100,0,0))
m[, machine := {lag.level = shift(level, 1, fill = 0); 
                ifelse(level != 0 | lag.level != 0, "on", "off") },]