使用if语句处理嵌套的for循环

时间:2019-07-15 11:12:57

标签: r loops for-loop

我有两列的数据框,第一是经度,第二是纬度。我想找到中心单元格的坐标。 例如如果两列的第一个值满足此条件,则范围为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
      }
    }    
  }
}

my data frame Expected results

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

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
     }
    }

2 个答案:

答案 0 :(得分:1)

我的解决方案避免了for循环,sapply或其他类似功能。代码的逻辑如下:由于范围的小数位数为.50或.00,因此居中值始终为.25或.75。这意味着我们只需要替换小数即可;所有介于.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

答案 1 :(得分:0)

# 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