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