繁体   English   中英

根据一个data.frame中的值和另一个条件中的条件返回向量

[英]Return a vector based on values in one data.frame and conditions in another

我有一个data.frame A,其中+100 000行包含位置信息(纬度=纬度,Lon =经度),另一个data.frame B,具有+500行包含地理区域的限制(区域不重叠)。

如何制作一个根据A中的位置从B返回地名的函数?

我希望R在B中存在某个位置时返回一个地名矢量,在一个位置不存在时返回“未分配”,而在A中缺少Lat或Lon时返回NA

例:

dataA <- structure(list(Lat = c(60L, 63L, 0L, 75L, NA, 71L, 70L), Lon = c(-70L, 
-66L, 5L, -100L, 80L, -61L, -150L)), .Names = c("Lat", "Lon"), class = "data.frame", row.names = c(NA, 
-7L))

dataB <- structure(list(Region = structure(c(2L, 3L, 1L), .Label = c("Beaufort Sea", 
"Hudson Strait", "North West Passage"), class = "factor"), Lat.min = c(55, 
70, 69.5), Lat.max = c(65L, 80L, 72L), Lon.min = c(-75L, -120L, 
-160L), Lon.max = c(-60L, -60L, -120L)), .Names = c("Region", 
"Lat.min", "Lat.max", "Lon.min", "Lon.max"), class = "data.frame", row.names = c(NA, 
-3L))

## I would like to test for each row in dataA:

i <- 1 ## i <- 1:nrow(dataB)
dataA$Lat > dataB$Lat.min[i] & dataA$Lat < dataB$Lat.max[i] &
dataA$Lon > dataB$Lon.min[i] & dataA$Lon < dataB$Lon.max[i]

## and return                                                                                                              
dataB$Region[i]  ## only once for each row of dataA,                                                                          
##unless is.na(dataA$Lat) | is.na(dataA$Lon), then return(NA),
##and if a row in dataA does not match any row in dataB, then return "not assigned"

## The result should look something like:
c("Hudson Strait", "Hudson Strait", "not assigned", "North West Passage", 
NA, "North West Passage", "Beaufort Sea")

我尝试过的ifelse以前使用ifelse函数已经解决了类似的难题,但是在这种情况下,我的条件data.frame太大了,无法手动完成。 我也尝试split data.frame A并运行条件for循环,但没有设法弄清楚如何制定for循环。 如果在循环内使用if语句,则循环返回的值与B中A行中每个行的值一样多。我还感觉到为此数据集运行for循环会花费很长时间,而不是提到分割后的data.frame A的大小。必须有一种更好的方法来执行此操作...

这是一种(当然不是最优雅的)方法:

z <- lapply(1:nrow(dataB), function(i){
  ifelse(is.na(dataA$Lat) | is.na(dataA$Lon), "Missing", 
ifelse(dataA$Lat > dataB$Lat.min[i] & dataA$Lat < dataB$Lat.max[i] &
 dataA$Lon > dataB$Lon.min[i] & dataA$Lon < dataB$Lon.max[i], 
as.character(dataB$Region[i]), NA))
  })

z <- do.call(rbind,z)

apply(z, 2, function(j) {
  out <-j[!is.na(j)]
  if(length(out) == nrow(z)) {
    return(NA)} else {
      if(length(out) > 0) {
      return(out)} else {
        return("Not assigned")
        }}
  })

# [1] "Hudson Strait" "Hudson Strait" "Not assigned" "North West Passage" 
# NA "North West Passage" "Beaufort Sea" 

也许有人有一个更优雅的解决方案?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM