【问题标题】:R - Compare two data frames of different length for same values in two columnsR - 比较两个不同长度的数据帧在两列中的相同值
【发布时间】:2015-05-01 00:14:24
【问题描述】:

这是一个关于如何比较两个不同长度的不同数据帧的几列的问题。

我有两个不同长度的数据帧(来自receiver1 (rec1) 和receiver2 (rec2) 的数据),其中包含4 艘不同船只的位置:

rec1 <- data.frame(name = sample (c("Nina", "Doug", "Alli", "Steve"), 20, replace = TRUE), 
                lon = sample (1:20), 
                lat = sample (1:10)
                )    
rec2 <- data.frame(name = sample (c("Nina", "Doug", "Alli", "Steve"), 30, replace = TRUE), 
                lon = sample (1:30),
                lat = sample (1:30)
                )

它们包含不同的名称(船名,两者的名称相同)和经度 (lon) 以及纬度 (lat) 坐标。

我正在尝试比较两个 dfs,以查看每艘船在“lon”和“lat”中匹配的值(即两个接收器接收相同位置的频率)

基本上我试图找出每个接收器有多好以及有多少数据点重叠(例如百分比)。

我不确定如何最好地做到这一点,并愿意接受任何建议。非常感谢!!!

【问题讨论】:

    标签: r compare


    【解决方案1】:

    这是一个经过修改且可重现的测试用例以及我的答案。我设计了测试集以包含匹配的组合和不匹配的组合。

    rec1 <- data.frame(shipName = rep(c("Nina", "Doug", "Alli", "Steve"), each = 5), 
                    lon = rep.int(c(1:5), 4), 
                    lat = rep.int(c(11:15), 4)
                    )    
    rec2 <- data.frame(shipName = rep(c("Nina", "Doug", "Alli", "Steve"), each = 7), 
                    lon = rep.int(c(2, 3, 4, 4, 5, 5, 6), 4),
                    lat = rep.int(c(12, 13, 14, 14, 15, 15, 16), 4)
                    )
    
    print(rec1)
    print(rec2)
    
    #Merge the two data frames together, keeping only those combinations that match
    m <- merge(rec1, rec2, by = c("shipName", "lon", "lat"), all = FALSE)
    
    print(m)
    

    如果您想计算每个组合出现的次数,请尝试以下操作。 (有不同的聚合方式。有些是here。下面是我的首选方法,它要求你安装data.table。这是一个很棒的工具,所以如果你还没有安装它,你可能想安装它。)

    library(data.table)
    
    #Convert to a data table and optionally set the sort key for faster processing
    m <- data.table(m)
    setkey(m, shipName, lon, lat)
    
    #Aggregate and create a new column called "Count" with the number of
        #observations in each group (.N)
    m <- m[, j = list("Count" = .N), by = list(shipName, lon, lat)]
    
    print(m)
    
    #If you want to return to a standard data frame rather than a data table:
    m <- data.frame(m)
    

    【讨论】:

    • Kevin,这是一个非常简洁的解决方案,非常适合我。非常感谢您花时间和精力!
    【解决方案2】:

    您没有构建一个非常有用的测试用例,但这里有一个方法:

    > both <- rbind(data.frame(grp="A", rec1[, 2:3]), data.frame(grp="B", rec2[, 2:3]))
    > with(both, table( duplicated(both[,2:3]), grp))
           grp
             A  B
      FALSE 20 30
    

    【讨论】:

    • 感谢您的快速回答,很抱歉测试用例不好,因为我不知道该怎么做,所以我只是举了一个简单的例子。
    • 您提供的代码运行良好,非常感谢!我想知道的是,从输出看来,它仅匹配两个数据集的 Lon 和 Lon 和 Lat 和 Lat,而不是寻找相同的 Lon 和 Lat 对。还是我弄错了?
    • 是的,这就是我的意图。我不认为 Lat 和 Lon 可以互换。
    • 我想我得到了解决方案,但我确实通过 grp 学到了一个有趣的新代码。非常感谢您的时间和精力!
    【解决方案3】:

    在基础 R 中进行这种比较的最简单方法是使用 merge。

    试试这个:

    # Set the RNG so sample() produces the same output and this example is reproducible
    set.seed(720) 
    
    rec1 <- data.frame(name = sample (c("Nina", "Doug", "Alli", "Steve"), 20, replace = TRUE), 
                lon = sample (1:20), 
                lat = sample (1:10)
                )    
    rec2 <- data.frame(name = sample (c("Nina", "Doug", "Alli", "Steve"), 30, replace = TRUE), 
                lon = sample (1:30),
                lat = sample (1:30)
                )
    
    merged <- merge(x = rec1,
                    y = rec2,
                    by = c("name","lat","lon"))
    
    print(merged)
    

    合并的数据框将包含所有三列都匹配的所有情况(在本例中为一)。然后,您可以执行table(merged$name) 之类的操作来计算每个名称在合并数据中出现的次数。

    不过,你的问题让我想知道......这里一定有某种时间元素,是吗?如果您在数据中包含测量时间,您可以通过 name 和 time 合并,然后计算测量的 lat 和 lon 差异。

    编辑:

    如果我不提到美妙的dplyr 包,我觉得我会失职,它使这样的分析变得非常简单。上面的唯一名称值的合并和计数是通过这个简单的单行实现的:

    inner_join(rec1, rec2) %>% count(name)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-25
      • 2016-01-03
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多