【问题标题】:ifelse statement inside for loop Rfor循环R中的ifelse语句
【发布时间】:2018-11-11 05:03:54
【问题描述】:

我目前正在处理一个非常大的海拔数据集,我需要根据 10m 间隔的分级海拔来为每一行归因于某些温度。因为数据集太大,我不能写一个简单的循环。我创建了一个较小的假数据集来展示我想要完成的工作。

elevation <- seq(0, 100, 10)

e <- runif(n=100,min=0,max=100)
lettertype <- c(rep("a", 25), rep("b", 25), rep("c", 50))
x <- data.frame(e, lettertype)

Winter <- runif(n=10, min=10, max=15)
Spring <- runif(n=10, min=12, max=16)
Summer <- runif(n=10, min=14, max=20)
Fall   <- runif(n=10, min=11, max=16)
elevbin <- c("0 to 10", "10 to 20", "20 to 30", "30 to 40", "40 to 50", 
              "50 to 60", "60 to 70", "70 to 80", "80 to 90", "90 to 100")
y <- data.frame(elevbin, Winter, Spring, Summer, Fall)

Wintertemp <- c()
for (i in 1:length(y$Winter)){
  for (j in 1:length(elevation)){
    for (k in 1:length(x$e)){
      Wintertemp <- c(Wintertemp, (ifelse(x$e[k] >= elevation[j] & x$e < elevation[j+1],  y$Winter[i], NA)))
    }
  }
}

本质上,高程是一个向量,它将告诉 for 循环每个 bin 内的高程(同样,由于数据集的大小,这必须自动化,跨越 200 个高程箱)。

  • 数据框 x 是我拥有的原始高程数据的一个示例,“字母类型”列并不重要,它只是将矢量 e 转换为数据框的附加组件。

  • 数据框 y 包含有关在每个海拔 bin 中表示哪些温度的信息(按季节,在此示例中,我只使用 Winter,但我需要为每个季节执行此操作)。

  • 我想将输出 cbind 到数据帧 x

例如:

head(x)
          e lettertype
1  5.801268          a
2 99.115869          a
3 31.928297          a
4 25.886745          a
5 93.288743          a
6 23.496359          a

y
     elevbin   Winter
1    0 to 10 12.51486
2   10 to 20 14.14977
3   20 to 30 10.19768
4   30 to 40 12.63925
5   40 to 50 10.18445
6   50 to 60 10.91821
7   60 to 70 13.00326
8   70 to 80 11.89128
9   80 to 90 13.88241
10 90 to 100 12.33358

所以我希望我的结果是:

head(x)
          e lettertype   Winter
1  5.801268          a 12.51486
2 99.115869          a 12.33358
3 31.928297          a 12.63925
4 25.886745          a 10.19768
5 93.288743          a 12.33358
6 23.496359          a 10.19768

简单来说,我想根据海拔箱中的温度为数据框 x 中的每个海拔(e)分配正确的温度。

当前代码返回一个长度为 1100000 的向量,其中包含 NA 和冬季向量中的第一个数字,这是不正确的。结果应该与 x 数据帧的长度相同。

任何帮助都会很棒!提前致谢!

【问题讨论】:

  • 您现有的循环是否有效,是否提供预期的输出?提供预期结果数据框会很好,也许有更好的做事方式,而不是尝试调试/改进现有代码。如果我们知道输入和预期输出,我们可能会尝试其他事情。顺便说一句,这个现有循环返回具有 1.1Mln 值的向量...
  • 我还建议您提供有关您想要实现的目标的其他信息。不要专注于技术问题,而是尝试用简单的语言来解释您想要实现的目标。例如,我不太了解“e”、“elevation”和 bin 之间的关系。提供一些真正的价值也可能是有意义的,这使我们更容易理解您的目标。
  • 现有循环不起作用。我用当前结果和预期结果更新了我的问题,希望这能提供更多信息。感谢您的帮助。

标签: r loops if-statement


【解决方案1】:

不需要for 循环或ifelse。如果您先创建适当的列,您可以merge 两个数据框:

elevation <- seq(0, 100, 10)

e <- c(seq(0, 99, 1))
elev_floor <- 10 * floor(e / 10)
x <- data.frame(e, elev_floor)

Winter <- runif(n=10, min=10, max=15)
Spring <- runif(n=10, min=12, max=16)
Summer <- runif(n=10, min=14, max=20)
Fall   <- runif(n=10, min=11, max=16)
elevbin <- c("0 to 10", "10 to 20", "20 to 30", "30 to 40", "40 to 50", 
             "50 to 60", "60 to 70", "70 to 80", "80 to 90", "90 to 100")
elev_floor <- seq(0, 90, 10)
y <- data.frame(elevbin, elevmin, Winter, Spring, Summer, Fall)

merge(x, y)

结果:

      e elev_floor   elevbin elevmin   Winter   Spring   Summer     Fall
1     0          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
2     1          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
3     2          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
4     3          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
5     4          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
6     5          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
7     6          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
8     7          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
9     8          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
10    9          0   0 to 10       0 12.53781 13.01907 16.74989 15.22208
11   10         10   0 to 10       0 12.53781 13.01907 16.74989 15.22208
12   11         10   0 to 10       0 12.53781 13.01907 16.74989 15.22208
13   12         10   0 to 10       0 12.53781 13.01907 16.74989 15.22208
14   13         10   0 to 10       0 12.53781 13.01907 16.74989 15.22208

如果您的 bin 比示例中的更复杂,则可以调整 x$elev_floor 的计算。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    相关资源
    最近更新 更多