我正在寻找一种更多矩阵/应用导向的方式来编写R中的状态机与我在这里用for循环和一堆if语句完成的操作?这是否可以在R中您需要知道机器的先前状态?
当A1和A2均为1时,以下机器启用;如果B1和B2均为1,则武装撤防.通常,A1,A2,B1和B1之间没有已知的关系.如果没有满足任何条件,则保持先前的状态.
是否有可能在R中进行这种计算而没有for循环逐步遍历矩阵?如果是这样,请创建一些计算S1a的代码.谢谢.
[[编辑简化]]
Mach1 = matrix(data=0, nrow = 24, ncol = 6)
colnames(Mach1)=c("A1","A2","B1","B2","S1","S1a")
Mach1[,"A1"] <- c(0,0,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0)
Mach1[,"A2"] <- c(0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0)
Mach1[,"B1"] <- c(0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0)
Mach1[,"B2"] <- c(0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1)
for (i in 2:nrow(Mach1)){
Prev = Mach1[(i-1),"S1"]
Prev = ifelse(is.na(Prev), 0, Prev)
Arm = ((Mach1[i,"A1"] ==1) && (Mach1[i,"A2"] == 1))
Disarm = ((Mach1[i,"B1"] == 1) && (Mach1[i,"B2"] == 1))
if ((Prev == 0) && (Arm)){ #Turn on
Mach1[i,"S1"] <- 1
print(paste(i, "Armed"))
} else if ((Prev == 1) && (Disarm)){ #Turn off
Mach1[i,"S1"] <- 0
print(paste(i, "Disarmed"))
} else {
Mach1[i,"S1"] <- Prev
print(paste(i, "---"))
}
}
rm(Arm, Disarm, Prev, i)
Run Code Online (Sandbox Code Playgroud)
使用包zoo你可以使用:
on <- with(as.data.frame(Mach1), A1 & A2)
off <- with(as.data.frame(Mach1), B1 & B2)
na.locf(c(1,0)[(!off) + 2*(!on)], na.rm=FALSE)
Run Code Online (Sandbox Code Playgroud)
结果
[1] NA NA NA NA NA 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
只需将NA初始机器状态替换为开头即可.