【问题标题】:matching columns of two different data frames in RR中两个不同数据帧的匹配列
【发布时间】:2014-12-02 15:37:00
【问题描述】:

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

【问题讨论】:

  • merge(...) 应该可以工作。你应该展示你的代码。

标签: r


【解决方案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")

【讨论】:

    【解决方案2】:

    由于这些是地理编码,需要注意的一件事是字段必须完全匹配。因此,例如,如果一个数据集的 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 方法将是最快的,但如果没有非常大的数据集(>1e5 行),您可能不会注意到差异。

    【讨论】:

      【解决方案3】:

      您可以为此使用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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-10
        • 1970-01-01
        • 1970-01-01
        • 2012-08-20
        • 2018-11-12
        • 2018-03-25
        • 1970-01-01
        相关资源
        最近更新 更多