匹配R中两个不同数据帧的列

时间:2014-12-02 15:37:01

标签: r

我有两个具有经度和纬度值的数据框,我想从数据帧#2(比如列df2$C,数据帧#2的第三列)中提取值,这些值与数据列匹配第1帧...例如,数据框1有两列(lonlat),数据帧2有三列(lonlat和一些value "C")...我想在数据框1中添加第三列,其中df2$C的值对应于两个数据框中与BOTH列完全匹配的值,比如df1$lon == df2$londf1$lat == df2$lat ...以及latlon对不匹配,我想添加一个NA,以便第三列(我想添加到数据。第1帧)的长度为= nrow(df1)。 我尝试了合并功能,但我遇到了将df1的两列与df2的列匹配的麻烦。

3 个答案:

答案 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)