首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R:根据另一个不同长度的数据帧中的条件给向量集赋值。

R:根据另一个不同长度的数据帧中的条件给向量集赋值。
EN

Stack Overflow用户
提问于 2016-02-08 14:29:31
回答 2查看 1.5K关注 0票数 1

我想给经度和纬度的值分配一个段-ID,这些值在一定的最小/最大长度范围内,而lat值存储在不同长度的数据帧中。我的数据看起来如下:带有观察的数据框架:

代码语言:javascript
复制
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的数据帧:

代码语言:javascript
复制
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

对于每一个观察点,我都想知道它落在哪一个“段”中,所以我理想的结局是这样的:

代码语言:javascript
复制
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

我试着用纬度来做这件事,但是由于向量的长度不同,我得到了一个错误消息。

代码语言:javascript
复制
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为止?

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-08 16:26:15

给定一个包含“经度”和“纬度”组件的向量x,函数f使用which.maxseg中找到合适的行。然后,apply(obs,1,f)是长度nrow(obs)的向量,它包含seg中适当段的行号。

代码语言:javascript
复制
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)] )

结果:

代码语言:javascript
复制
> 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>
票数 1
EN

Stack Overflow用户

发布于 2016-02-08 17:45:46

您的经度和纬度在两个数据帧之间混在一起。

另外,您的示例数据使您不可能匹配您的obs和seg,因为您所有的纬度都小于lat_min的查找量。

尽管如此,这应该是可行的。你在试着做一个查找表。

代码语言:javascript
复制
#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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35272049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档