【问题标题】:Incomplete for loop with two if-statements带有两个 if 语句的不完整 for 循环
【发布时间】:2017-11-21 10:43:45
【问题描述】:

我已经在这个网站上搜索了很长一段时间,但无法找到我的问题的答案。

我正在研究一条小溪的几个属性之间的相关性,这些属性都收集在一个数据框 (PEQTfXS_GrooteMolenbeek) 中。目前我正专注于这条小溪的排放 (PEQTfXS_GrooteMolenbeen$Q)。我想要做的是在放电数据中运行一个 for 循环,如果当前值小于前一个值,则分配红色。如果当前值大于前一个值,将分配蓝色。最后,如果可能的话,我想创建一个红色和蓝色数据点与时间的关系图(PEQTfXS_GrooteMolenbeek$date)。

我现在的循环如下:

for (i in 1:length(PEQTfXS_GrooteMolenbeek$Q){
if PEQTfXS_GrooteMolenbeek$Q[i] < PEQTfXS_GrooteMolenbeek$Q[i-1] col = "red"
if PEQTfXS_GrooteMolenbeek$Q[i] > PEQTfXS_GrooteMolenbeek$Q[i-1] col = "blue"
}

这个循环似乎缺少一些东西,但我不知道是什么。除此之外,我想知道如何实现我的问题的绘图部分。

希望这个问题不会太愚蠢。我知道有比 for 循环更简单的方法,但我对那些不感兴趣 ;)

谢谢!

【问题讨论】:

    标签: r for-loop if-statement


    【解决方案1】:

    虽然我更喜欢Milan Valášek 的解决方案,因为它是更优雅的 R 风格,但我想提供一个答案,涵盖您关于 for 循环和 if 语句的语法的部分问题。我使用了一些示例性数据,因为没有可重复的示例可用。我希望这对语法有所帮助。

    #generate example data
    #since your values are integers and your colour codes are characters
    #you need separate columns to store them
    #character vectors would not be allowed in an integer vector
    #(of course you could turn the full vector to character,
    #but this would be make the code unnecessarily complex)
    values <- rep(c(1,2), 5)
    value_color <- rep("", length(values))
    df <- data.frame(values = values
                     , value_color = value_color
                     , stringsAsFactors = F)
    
    #since you index i-1, the first entry needs to be decided manually
    df[1, "value_color"] <- "red"
    
    #first entry skipped due to manual assignment
    #note the brackets around the definition of the loop indices
    for (i in 2:length(values) ) {
    
      #note the brackets around the definition of the expression to
      #be checked via if
      #best practice is to use curly brackets and new line to open if statements
      #for better readability
      #the if statements checks the values in the numeric column called value...
      if (df[i, "values"] < df[i-1, "values"]) {
    
        #...and assigns the corresponding value in the character column
        df[i, "value_color"]  <- "red"
    
      } else if (df[i, "values"]  > df[i-1, "values"]) {
    
        df[i, "value_color"]  <- "blue"
    
      }
    }
    
    df
    
    #      values value_color
    # 1       1         red
    # 2       2        blue
    # 3       1         red
    # 4       2        blue
    # 5       1         red
    # 6       2        blue
    # 7       1         red
    # 8       2        blue
    # 9       1         red
    # 10      2        blue
    

    【讨论】:

    • 就像你说的那样,不是这样做的方法,而是很好地说明for/if。也许注释代码以增加教学价值?
    • ...注释代码,希望它通过你的教学质量测试 ;-)
    • 这很有帮助!然而,有一个小问题。我的数据包含相当多的NA。此时,循环在遇到第一个 NA 时会出错。如何让循环跳过这些值?
    • 取决于您希望循环执行的操作。您没有在问题中指出您有 NA 值或如何处理它们,因此,我没有考虑 NA 值。您只需添加涵盖 NA 值的 ifelse 语句。我想,在这种情况下,您只是想通过next(i) 告诉 R 转到下一个元素,而不是在循环中执行完整的代码。
    【解决方案2】:

    只需为您的条件创建一个因子变量编码,例如:

    PEQTfXS_GrooteMolenbeek$group <- NA
    PEQTfXS_GrooteMolenbeek$group[-1] <- PEQTfXS_GrooteMolenbeek$Q[-1] > PEQTfXS_GrooteMolenbeek$Q[-nrow(EQTfXS_GrooteMolenbeek)]
    PEQTfXS_GrooteMolenbeek$group <- as.factor(PEQTfXS_GrooteMolenbeek$group)
    

    (在您上面的代码中,没有规定值相等的情况。上面的代码会将这些情况放在第一组中)

    然后您可以使用 例如 base plot()ggplot2 包创建您的绘图,并使用 group 变量为不同颜色编码。比如:

    library(ggplot2)
    qplot(date, Q, color = group, data = PEQTfXS_GrooteMolenbeek)
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多