【问题标题】:Optimising R function that adds a new column to a data.frame优化将新列添加到 data.frame 的 R 函数
【发布时间】:2010-12-30 19:21:38
【问题描述】:

我有一个功能,目前在功能模型中编程,要么想加快它的速度,要么本着 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))
}

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    如果没有样本数据,我无法对此进行测试,但这是总体思路。您可以通过使用&amp;| 完全避免执行for() 循环,它们是&amp;&amp;|| 的矢量化版本。此外,如果只有一个值(真或假),则不需要 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。

    【讨论】:

    • 既然idx是合乎逻辑的,group &lt;- as.numeric(idx)就足够了。
    【解决方案2】:

    这可以通过将您的程序分成两部分以更加矢量化的方式完成:首先是一个函数,它需要两个时间样本并确定它们是否符合您的脉冲规范:

    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 表示假,T 表示真)

    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
    

    【讨论】:

      猜你喜欢
      • 2019-09-29
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多