[英]Optimising R function that adds a new column to a data.frame
我有一个目前已在功能模型中编程的函数,或者想加快它的运行速度,也许可以按照R的精神来解决更多问题。我有一个data.frame,并希望根据每个地方的信息添加一个列条目取决于两行。 目前,其外观如下:
faultFinging <- function(heartData){
if(heartData$Pulse[[1]] == 0){
Group <- 0
}
else{
Group <- 1
}
for(i in seq(2, length(heartData$Pulse), 1)){
if(heartData$Pulse[[i-1]] != 0
&& heartData$Pulse[[i]] != 0
&& abs(heartData$Pulse[[i-1]] - heartData$Pulse[[i]])<20){
Group[[i]] <- 1
}
else{
if(heartData$Pulse[[i-1]] == 0 && heartData$Pulse[[i]] != 0){
Group[[i]] <- 1
}
else{
Group[[i]] <- 0
}
}
}
Pulse<-heartData$Pulse
Time<-heartData$Time
return(data.frame(Time,Pulse,Group))
}
没有示例数据,我无法测试这一点,但这是一般的想法。 您可以通过使用&
和|
来完全避免for()
循环|
是&&
和||
向量化版本 。 另外,如果只有一个值(真或假),则无需if-else语句。
faultFinging <- function(heartData){
Group <- as.numeric(c(heartData$Pulse[1] != 0,
(heartData$Pulse[-nrow(heartData)] != 0
& heartData$Pulse[-1] != 0
& abs(heartData$Pulse[-nrow(heartData)] - heartData$Pulse[-1])<20) |
(heartData$Pulse[-nrow(heartData)] == 0 & heartData$Pulse[-1] != 0)))
return(cbind(heartData, Group))
}
将as.numeric()
放在索引周围会将TRUE设置为1,将FALSE设置为0。
可以通过将程序分为两部分来以更向量的方式完成此操作:首先,该函数需要两个时间样本并确定它们是否满足您的脉冲规范:
isPulse <- function(previous, current)
{
(previous != 0 & current !=0 & (abs(previous-current) < 20)) |
(previous == 0 & current !=0)
}
注意使用矢量|
代替布尔||
。
然后调用它,提供两个向量流“上一个”和“当前”偏移适当的延迟,在您的情况下为1:
delay <- 1
samples = length(heartData$pulse)
isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])
让我们对一些虚构数据进行尝试:
sampleData = c(1,0,1,1,4,25,2,0,25,0)
heartData = data.frame(pulse=sampleData)
result = isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])
请注意,对于前一个流,代码heartData$pulse[-(samples-(1:delay))]
从结尾处修剪delay
样本,而heartData$pulse[-(1:delay)]
从开始处修剪delay
样本,用于当前流。
手动执行,结果应该是(使用F
表示false,使用T
表示true)
F,T,T,T,F,F,F,T,F
通过运行它,我们发现它们是!:
> print(result)
FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE
成功!
由于您希望将它们作为一列绑定回原始数据集中,因此应注意,新数组的delay
元素比原始数据短,因此您需要在开始时使用延迟FALSE元素进行填充。 您可能还希望根据数据将其转换为0,1:
resultPadded <- c(rep(FALSE,delay), result)
heartData$result = ifelse(resultPadded, 1, 0)
这使
> heartData
pulse result
1 1 0
2 0 0
3 1 1
4 1 1
5 4 1
6 25 0
7 2 0
8 0 0
9 25 1
10 0 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.