我有两个具有经度和纬度值的数据框,我想从数据帧#2(比如列df2$C
,数据帧#2的第三列)中提取值,这些值与数据列匹配第1帧...例如,数据框1有两列(lon
,lat
),数据帧2有三列(lon
,lat
和一些value "C"
)...我想在数据框1中添加第三列,其中df2$C
的值对应于两个数据框中与BOTH列完全匹配的值,比如df1$lon == df2$lon
和df1$lat == df2$lat
...以及lat
,lon
对不匹配,我想添加一个NA
,以便第三列(我想添加到数据。第1帧)的长度为= nrow(df1)
。
我尝试了合并功能,但我遇到了将df1
的两列与df2
的列匹配的麻烦。
答案 0 :(得分:1)
您可以尝试data.table
library(data.table)
setDT(df1)
setkey(setDT(df2), lat, lon)
df2[df1]
# lat lon C
#1: 58 1 NA
#2: 52 10 NA
#3: 54 7 -0.9094088
#4: 60 2 NA
#5: 50 3 1.4541841
#6: 56 9 -1.7771135
#7: 59 5 NA
#8: 55 8 NA
#9: 53 4 NA
#10: 57 6 NA
df1 <- structure(list(lat = c(58L, 52L, 54L, 60L, 50L, 56L, 59L, 55L,
53L, 57L), lon = c(1L, 10L, 7L, 2L, 3L, 9L, 5L, 8L, 4L, 6L)), .Names = c("lat",
"lon"), row.names = c(NA, -10L), class = "data.frame")
df2 <- structure(list(lat = c(51L, 55L, 50L, 58L, 56L, 57L, 60L, 54L,
52L, 54L), lon = c(13L, 10L, 3L, 6L, 9L, 8L, 9L, 16L, 4L, 7L),
C = c(1.48642005012902, 1.53314455225747, 1.45418413640182,
-0.874122129771392, -1.77711353745745, 0.128866710402714,
-2.41118134931725, -1.78305563078752, -0.0173287724390305,
-0.909408846416724)), .Names = c("lat", "lon", "C"), row.names = c(NA,
-10L), class = "data.frame")
答案 1 :(得分:1)
由于这些是地理编码,因此需要注意的是字段必须完全匹配。因此,例如,如果一个数据集具有lon / lat到6个有效数字,而另一个数据集具有lon / lat到8个有效数字,则不会得到匹配(或非常少)。我想知道这是merge(...)
不适合你的原因。如下所示,它应该可以工作。
merge(...)
应该有效,特别是如果两个数据框具有相同的列名。使用来自@ akrun答案的数据集:
merge(df1,df2, by=c("lon","lat"),all.x=TRUE)
# lon lat C
# 1 1 58 NA
# 2 2 60 NA
# 3 3 50 1.4541841
# 4 4 53 NA
# 5 5 59 NA
# 6 6 57 NA
# 7 7 54 -0.9094088
# 8 8 55 NA
# 9 9 56 -1.7771135
# 10 10 52 NA
如果您未指定by=...
参数,merge(...)
将使用所有常用列,因此在这种情况下您只需编写:
merge(df1,df2,all.x=TRUE)
您还可以使用join(...)
plyr
包。
library(plyr)
join(df1,df2)
所有这些选项都会产生相同的结果,尽管行的顺序不同。
data.table方法将是最快的,虽然没有非常大的数据集(&gt; 1e5行),您可能不会注意到差异。
答案 2 :(得分:0)
您可以使用ifelse
。例如,使用数据:
df1 <- structure(list(lat = c(58L, 52L, 54L, 60L, 50L, 56L, 59L, 55L,
53L, 57L), lon = c(1L, 10L, 7L, 2L, 3L, 9L, 5L, 8L, 4L, 6L)), .Names = c("lat",
"lon"), row.names = c(NA, -10L), class = "data.frame")
df2 <- structure(list(lat = c(51L, 55L, 50L, 58L, 56L, 57L, 60L, 54L,
52L, 54L), lon = c(13L, 10L, 3L, 6L, 9L, 8L, 9L, 16L, 4L, 7L),
C = c(1.48642005012902, 1.53314455225747, 1.45418413640182,
-0.874122129771392, -1.77711353745745, 0.128866710402714,
-2.41118134931725, -1.78305563078752, -0.0173287724390305,
-0.909408846416724)), .Names = c("lat", "lon", "C"), row.names = c(NA,
-10L), class = "data.frame")
您可以使用
为df1创建列C.ifelse(df1[,'lat'] %in% df2[,'lat'] & df1[,'lon'] %in% df2[,'lon'],df2$C,NA)