【问题标题】:working with nested for loop with if statment使用 if 语句处理嵌套 for 循环
【发布时间】:2019-07-18 12:26:57
【问题描述】:

我有一个两列的数据框,第一是经度,第二是纬度。我想找到中心单元格的坐标。 例如范围是 lat[31 31.5], lon[33 33.5] 如果两列的第一个值满足此条件,则创建第三列并放入值 31.25 并创建第四列并将值放入其中 33.25

我尝试过嵌套for循环,但它不起作用

# my dataframe is cycle8 contain 166 rows and two columns
latitude<- seq(31,37,by=0.5)
longitude<- seq(33,37,by=0.5)
cycle8$latcenter<- 0
cycle8$loncenter<-0
for (m in 1:nrow(cycle8)) 
{
  for(j in seq_along(latitude))
  {
    for(k in seq_along(longitude))
    {    
      if (cycle8$lat[m]>=j && cycle8$lat[m]<=j+0.5 && cycle8$lon[m]>=k && 
          cycle8$lon[m]<=k+0.5)
      {
        cycle8$latcenter[m]<- j+0.25

        cycle8$loncenter[m]<- k+0.25
      }
    }    
  }
}

以下代码可以运行并提供所需的结果,但它很长并且需要大量的语句输入

cycle8$latcenter<- 0

for (m in 1:nrow(cycle8)) 
{

   if (cycle8$lat[m]>=31 && cycle8$lat[m]<=31.5 )
   {
     cycle8$latcenter[m]<- 31+0.25
   }
     else if
       (cycle8$lat[m]>=31.5 && cycle8$lat[m]<=32 ){
       cycle8$latcenter[m]<- 31.5+0.25
     }
     else if
       (cycle8$lat[m]>=32 && cycle8$lat[m]<=32.5 ){
       cycle8$latcenter[m]<- 32+0.25
     }
     else if
       (cycle8$lat[m]>=32.5 && cycle8$lat[m]<=33 ){
       cycle8$latcenter[m]<- 32.5+0.25
     }
     else if
       (cycle8$lat[m]>=33 && cycle8$lat[m]<=33.5 ){
       cycle8$latcenter[m]<- 33+0.25
     }
     else if
       (cycle8$lat[m]>=33.5 && cycle8$lat[m]<=34 ){
       cycle8$latcenter[m]<- 33.5+0.25
     }
     else if
       (cycle8$lat[m]>=34 && cycle8$lat[m]<=34.5 ){
       cycle8$latcenter[m]<- 34+0.25
     }
     else if
       (cycle8$lat[m]>=34.5 && cycle8$lat[m]<=35 ){
       cycle8$latcenter[m]<- 34.5+0.25
     }
     else if
       (cycle8$lat[m]>=35 && cycle8$lat[m]<=35.5 ){
       cycle8$latcenter[m]<- 35+0.25
     }
     else if
       (cycle8$lat[m]>=35.5 && cycle8$lat[m]<=36 ){
       cycle8$latcenter[m]<- 35.5+0.25
     }
     else if
       (cycle8$lat[m]>=36 && cycle8$lat[m]<=36.5 ){
       cycle8$latcenter[m]<- 36+0.25
     }
     else if
       (cycle8$lat[m]>=36.5 && cycle8$lat[m]<=37 ){
       cycle8$latcenter[m]<- 36.5+0.25
     }
    }

【问题讨论】:

  • 在您的示例中,有 [31 31.5] 之外的 lat 值,但预期输出会根据您描述的满足此条件的值对它们进行四舍五入。所以对我来说,您似乎只是想四舍五入 0.25?
  • 在我的代码中,我添加了数据框“cycle8”,我有 166 个纬度值和 166 个经度值。如果这些纬度和经度属于范围,我想进行测距,那么我想创建包含范围中心值的新列
  • 我这里只上传了前十行,其余行包含更多的lon和lat的值我想检查以下范围lat [31 31.5],[31.5 32],[32 32.5], [32.5 34] 依此类推,直到 [36.5 37],同样地,lon [33 33.5] 依此类推,直到 [36.5 37]
  • 这个问题要更清楚,我会解释给你。 lon 列的第一个值是 33.350407 我想编写代码来检查这个值属于哪个范围,它属于 [33 33.5],然后在新列中放入这个范围中心的值,即 33.25

标签: r loops for-loop


【解决方案1】:

我的解决方案避免使用 for 循环、sapply 或其他类似功能。代码背后的逻辑如下:由于范围的小数点为 0.50 或 .00,因此居中的值将始终为 0.25 或 0.75。这意味着我们只需要替换小数即可; 0.00 和 .50 之间的所有小数变为 .25,而其他小数变为 .75。

这里是代码

# generate data
latitude <- seq(30, 32, .1)
longitude <- seq(30, 32, .1)
cycle8 <- data.frame(latitude, longitude)

# make a function that replaces decimals as explained above
lat_lon <- function(vec){
decimals <- as.character(format(vec, nsmall= 1))
decimals <- as.numeric(gsub("^.*\\.", "", decimals))
decimals <- ifelse(decimals < 5, .25, .75)
values <- as.numeric(gsub("\\..*","",vec)) + as.numeric(decimals)
return(values)
}

# apply function
cycle8$lat_center <- lat_lon(latitude)
cycle8$lon_center <- lat_lon(longitude)

# see results
cycle8

编辑

因为您希望 30.00 为 29.75 而 30.50 为 30.25,所以这里进行了修改。但是逻辑还是一样的。

latitude <- seq(30, 32, .1)
longitude <- seq(30, 32, .1)
cycle8 <- data.frame(latitude, longitude)
lat_lon <- function(vec){
decimals <- as.character(format(vec, nsmall= 1))
decimals <- as.numeric(gsub("^.*\\.", "", decimals))
decimals_new <- ifelse(decimals > 5 | decimals == 0, .75, .25)
values <- as.numeric(gsub("\\..*","",vec)) + as.numeric(decimals_new)
values[decimals == 0] <- values[decimals == 0] - 1
return(values)
}
cycle8$lat_center <- lat_lon(latitude)
cycle8$lon_center <- lat_lon(longitude)
cycle8

【讨论】:

  • 不是这样,cycle8 包含带小数的 lon 和 lat 的值,以及 latitude
  • 好吧,我不明白。也许其他人可以提供帮助!
  • 无论如何谢谢你,至少你已经尽力帮忙了。但我会进一步澄清。除了这段代码,假设我在第一行有一个值 10.23 并且我有一个范围 [10 10.5] 问题是检查 10.23 是否属于这个范围,如果是,然后创建一个新列并放入它(10+10.5)/2 的值是 10.25 或者检查第二个范围,例如[10.5 11] 等等。现在移动到第二行,其中包含例如值 10.56 并再次检查,直到我们完成第一列的所有行。
  • @Jisika:我的代码将完全返回:例如,round(10.23/.25)*.25 返回 10.25。上面的代码应该总是给出你想要的结果(除非有我不知道的特殊情况)。您是否尝试过并观察到任何意想不到的结果?
  • 它不起作用,例如对于值 33.57776,您的代码结果是 33.5,但我想要的结果应该是 33.75,因为 33.57776 属于 [33.5 34]
【解决方案2】:
# The other way of solving this question is 
mydata<- c(35.666,35.4578,35.0, 33.50,32.10)
centered_value <- function(val){ 
                               a<- trunc(val)
                               b<- val %% 1
 c<- ifelse(b/0.5 > 1, a +0.75 , ifelse(b/0.5> 1, a+0.25, ifelse(b/0.5 ==0, a- 
                                                                      0.25,a+0.25)))
                               }
       d<- centered_value(mydata)
       d

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    相关资源
    最近更新 更多