[英]R: assign values to set of vectors based on conditions in another data frame of different length
我想將段ID分配給經度和緯度值,這些值落在存儲在不同長度的不同數據幀中的最小/最大長度和緯度值的特定范圍內。 我的數據如下所示:帶有觀察的數據框:
head(obs)
longitude latitude
52.06264 6.412816
52.06097 6.413106
51.06097 6.413346
54.06097 6.413276
51.06089 6.413114
52.05444 6.413094
包含范圍和段ID的數據框:
head(seg)
segment lon_max lon_min lat_max lat_min
01a 6.857822 6.857476 51.05837 51.03489
01b 6.858979 6.857834 51.03433 50.99901
01c 6.860019 6.858982 51.99836 51.96330
01d 6.860960 6.860050 51.96277 51.92718
01e 6.862294 6.860979 51.92657 51.89125
01f 6.863179 6.862301 51.89059 51.85562
對於每個觀察點,我想知道它落在哪個“段”中,所以我最終會得到這樣的結果:
longitude latitude segment
52.03464 6.458816 1a
52.05667 6.416606 1a
51.06097 6.446346 1b
54.03757 6.413276 1c
51.06089 6.422114 1b
52.34243 6.413094 1a
我試圖僅使用緯度來做這個,但由於向量的長度不同,我得到一條錯誤信息。
obs[['segment']] <- for (i in obs$latitude) {
if (i>=seg$lat_min & i<=seg$lat_max) {
obs$segment=seg$segment
} else {
obs$segment='NA'}
}
Error in `$<-.data.frame`(`*tmp*`, "segment", value = 1:118) :
replacement has 118 rows, data has 10284
我知道為什么這不起作用,因為它不是逐行匹配,但我不知道如何做到這一點。 如何逐行匹配每對緯度和經度與最小/最大值,直到找到它適合的范圍並分配正確的segment_ID?
提前致謝!
您的經度和緯度在兩個數據框架中混淆了。
此外,您的示例數據使得無法匹配您的obs和seg,因為您的所有緯度(例如緯度)都小於lat_min的查找值。
盡管如此,這應該有效。 你正試圖做一個查找表。
#create this so we have validation data
newline <- c( 51.05837, 6.857822)
newobs <- rbind(obs, newline)
library(sqldf)
looked_up<-function(data, lookup){
data<-sqldf("select A.*,B.segment from
data A left join lookup B
ON (A.longitude >= B.lon_min and A.longitude
<= B.lon_max and A.latitude >= B.lat_min and A.latitude
<= B.lat_max) ")
data
}
looked_up(newobs, seg)
#RESULTS
longitude latitude segment
1 52.06264 6.412816 <NA>
2 52.06097 6.413106 <NA>
3 51.06097 6.413346 <NA>
4 54.06097 6.413276 <NA>
5 51.06089 6.413114 <NA>
6 52.05444 6.413094 <NA>
7 51.05837 6.857822 01a
我在回答你的問題時覺得這很有幫助。
http://shashiasrblog.blogspot.com/2014/01/excel-style-vlookup-and-rangelookup-in-r.html
給定具有“經度”和“緯度”分量的向量x
,函數f
使用which.max
來找到seg
的適當行。 然后apply(obs,1,f)
是長度為nrow(obs)
的向量,其中包含seg
相應段的行號:
obs <- read.table( header = TRUE,
text =
"latitude longitude
52.06264 6.412816
51.90089 6.861084
52.06097 6.413106
51.06097 6.413346
54.06097 6.413276
51.04097 6.857576
51.06089 6.413114
51.95089 6.860084
52.05444 6.413094" )
seg <- read.table( header = TRUE,
stringsAsFactors = FALSE,
text =
"segment lon_max lon_min lat_max lat_min
01a 6.857822 6.857476 51.05837 51.03489
01b 6.858979 6.857834 51.03433 50.99901
01c 6.860019 6.858982 51.99836 51.96330
01d 6.860960 6.860050 51.96277 51.92718
01e 6.862294 6.860979 51.92657 51.89125
01f 6.863179 6.862301 51.89059 51.85562")
f <- function(x)
{
which.max( c( ( seg["lon_min"] <= c(x["longitude"]) ) &
( seg["lon_max"] > c(x["longitude"]) ) &
( seg["lat_min"] <= c(x["latitude"]) ) &
( seg["lat_max"] > c(x["latitude"]) ),
TRUE ) )
}
X <- cbind( obs, segment = seg$segment[apply(obs,1,f)] )
結果:
> X
latitude longitude segment
1 52.06264 6.412816 <NA>
2 51.90089 6.861084 01e
3 52.06097 6.413106 <NA>
4 51.06097 6.413346 <NA>
5 54.06097 6.413276 <NA>
6 51.04097 6.857576 01a
7 51.06089 6.413114 <NA>
8 51.95089 6.860084 01d
9 52.05444 6.413094 <NA>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.