【问题标题】:Manage the number of ELSEs in IF-ELSE statement管理 IF-ELSE 语句中的 ELSE 数量
【发布时间】:2015-09-16 15:37:03
【问题描述】:

这是我的数据框的样子:

set.seed(1)
df <- data.frame(Period = seq(1:13)
                 , Units = c(1,2,rep(1, 3), rep(2, 4), rep(3, 4))
                 , Temperature = rnorm(13, 25, 5)
                 )

我想测量 Units 值更改前后的平均温度。最重要的是,我只想在 Units 的值在更改前后至少 4 个周期内保持稳定时才测量平均值。

所以,我认为这个过程可以分成几个部分:

  1. 查找每次更改发生的位置。
  2. 检查前 4 个周期和后 4 个周期的 Units 值是否相等。其他 - 下次更改单位时尝试。
  3. 如果 2 为 TRUE - 计算这些时期的平均温度。

对于第一步,我创建了一个包含单位变化位置的变量:

for (i in 1:length(which(diff(df$Units) != 0))){
  assign(paste("change_", i, sep=""), which(diff(df$Units) != 0)[i])
}

第二步,我用 IF-ELSE 检查,然后将第三步嵌套在里面:

if (change_1>=4
  &&(df$Units[change_1] == df$Units[change_1-1])
  && (df$Units[change_1] == df$Units[change_1-2])
  && (df$Units[change_1] == df$Units[change_1-3])
  && (df$Units[change_1] == df$Units[change_1-4])){

  old_mean <- mean(c(df$Temperature[change_1]
                     , df$Temperature[change_1-1]
                     , df$Temperature[change_1-2]
                     , df$Temperature[change_1-3]))

  new_mean <- mean(c(df$Temperature[change_1+1]
                     , df$Temperature[change_1+2]
                     , df$Temperature[change_1+3]
                     , df$Temperature[change_1+4]))
}

当然,如果第一次发生变化,IF条件为FALSE,那么在else if中我会检查change_2前后是否有4个稳定单元.所以最后,使用上面的示例,对于 old_mean,我希望代码输出 mean(df$Temperature[6:9]) 或 26.22633 的结果。

这不是最佳的,因为我想跨多个数据帧运行它,其中更改的数量会有所不同。 因此,我需要根据 change_n 变量的数量来管理 else if 语句的数量。

谁能建议如何自动告诉 R 应该有多少个 Else-If? 如果您可以提出更实用的方法来完成这项工作,请加分。

【问题讨论】:

  • 你也可以添加一个预期的输出吗?它通常使遵循逻辑流程变得更加容易。
  • 您的预期输出是什么?真的很难按照自己的方式进行。
  • 请看我上面的编辑。

标签: r if-statement


【解决方案1】:

每次发生更改时生成一个新变量并不是完成您想做的事情的理想方式。一般来说(即不仅仅是在使用 R 编程时)如果您正在考虑动态生成一堆变量,那么创建数组或向量会更好。

在这种情况下,创建一个向量,它将索引属于一组连续相同单元类型的每个单元。然后,使用这个新向量和by() 函数,您可以获得平均值。执行此操作的一些代码是:

rep.threshold <- 4 #variable that will let you change how many repetitions before it "counts"
units.grp <- rep(0,length(df$Units)) #vector of indices for units
grp.id <- 1 #variable to store current index
repeats <- 1 #variable that tracks how many time unit has repeated

for(i in 2:length(df$Units)){
    #if current unit equal to last unit, increment number of repeats counted so far
    if(df$Units[i]==df$Units[i-1]) repeats <- repeats+1

    #otherwise, reset repetition count and increment group if at the end of a running group
    else{
        if(repeats>=rep.threshold) grp.id <- grp.id+1
        repeats<-1
    }

    #if there have been enough repeats, write group index into vectorfor all matches
    if(repeats>=rep.threshold) units.grp[(i-rep.threshold+1):i]<-rep(grp.id,rep.threshold)
}

对于您的示例数据框,上面的代码将生成[0 0 0 0 0 1 1 1 1 2 2 2 2] 的向量

现在,您还可以使用by(df$Temperature, units.grp, mean) 获取每个索引组的平均值(作为所有重复次数不足的温度的平均值,它将显示为组 0)。

【讨论】:

  • 非常好的解决方案!您能否提出一种简洁的方法来计算更改发生前后 4 周的平均值?
  • @NikolayNenov 测量时间是否作为另一列存储在数据框中?如果不是,是否总是以固定的时间间隔进行测量(即每小时测量一次)?
猜你喜欢
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 2015-10-28
  • 2020-11-23
  • 2017-02-05
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多