子集数据框基于多个条件的唯一组合

时间:2013-05-13 08:51:32

标签: r match subset

我似乎无法通过搜索来找到答案。我正在尝试根据四个条件选择data.frame的子集( lon1 lon2 lat1 LAT2 )。我有一个巨大的相异矩阵,它已被矢量化并且站点( lon1 lon2 lat1 lat2 cbind到它。这是一个示例数据框:

out1 <- data.frame(lon1 = sample(1:10), lon2 = sample(1:10), 
                   lat1 = sample(1:10), lat2 = sample(1:10), 
                   dissimilarity = sample(seq(0,1,.1),10))
> out1
     lon1   lon2    lat1 lat2 dissimilarity
1     2      6      4      4           0.6
2     4      2      1      3           1.0
3    10      9      2      6           0.0
4     3      1     10      8           0.5
5     9      5      9      1           0.8
6     5      7      5      9           0.9
7     1      8      6      7           0.2
8     8      3      8      5           0.7
9     7      4      3     10           0.3
10    6     10      7      2           0.1

out2 <- out1[c(2,5,6,8),]

   lon1 lon2 lat1 lat2 dissimilarity
1     4   2   1      3           1.0
2     9   5   9      1           0.8
3     5   7   5      9           0.9
4     8   3   8      5           0.7

我尝试以这种方式使用%in%函数几次:

test <- out1[(out1$lon1 %in% out2$lon1) & (out1$lon2 %in% out2$lon2) & 
             (out1$lat1 %in% out2$lat1) & (out1$lat2 %in% out2$lat2), ]

这似乎适用于我在此提供的基本示例。但是,当我将它应用到我的庞大数据框(重复了许多latlons)时,我得到的回归比我需要的 unqiue 组合更大。我假设因为%in%中的匹配函数只能匹配一个向量。因此匹配条件1 & condition2 & condition3 & condition4因此返回的结果给出了与原始out1相同的子集。我想只得到该行的所有四个值相同的情况。通过这种方式,我将获得我感兴趣的成对差异的数据子集。

有关如何基于四个变量的独特组合按行分组的任何想法都将非常感激。

1 个答案:

答案 0 :(得分:2)

我认为这就是你要找的东西。基本上你想要duplicated函数返回你期望的东西。

out1[duplicated(rbind(out2, out1)[, 1:4])[-seq_len(nrow(out2))], ]

它是如何工作的?首先我们rbind out2out1。然后在其上调用duplicatedout2out1中的列将在TRUE中标记为out1。这是因为第一次出现在out2上并且在那里没有重复。但是第二次找到条目时,它会在out1中,所以它会知道之前有一个完全相同的行。所以,它会将其标记为重复。我们现在拥有所有重复的条目。通过删除out1中的第一个n元素,我们仅对n = nrow(out1)的元素进行了子集。然后我们使用out1上的逻辑向量进行子集化。

您可以查看此说明并逐步运行代码以进行跟进。这是一个用于计算逻辑的细分版本。

tt <- rbind(out2, out1)
tt.dup <- duplicated(tt[, 1:4)] # marks all duplicate rows in out1 from 1st 4 cols
tt.dup <- tt.dup[-seq_len(nrow(out2))] # remove all out2 entries (first n)
out1[tt.dup, ] # index only TRUE/duplicated elements from out1