簡體   English   中英

R:基於不同長度的另一數據幀中的條件,將值分配給矢量集

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM