聚合所有可能的唯一组合与 R 中同一列中的观察值

Aggregation of all possible unique combinations with observations in the same column in R

我正在尝试缩短一段代码,以使其更快、更容易修改。这是我的数据的一个简短示例。

   order obs year var1 var2 var3
1      3   1    1   32  588   NA
2      4   1    2   33  689 2385
3      5   1    3   NA  678 2369
4     33   3    1   10  214 1274
5     34   3    2   10  237 1345
6     35   3    3   10  242 1393
7     78   6    1    5   62   NA
8     79   6    2    5   75  296
9     80   6    3    5   76  500
10    93   7    1   NA   NA   NA
11    94   7    2    4   86  247
12    95   7    3    3   54  207

基本上,我想要的是 R 在同一年内在 "obs" 列中找到两个值(观察值)的任何可能且唯一的组合,以创建一个新的矩阵或 DF,其中观察值是聚合的原件。顺序并不重要,所以 1+6 = 6+1。例如,有 150 个观察值,我预计有 11,175 个可行组合(每年)。

我用基本的编码得到了我想要的东西,但是,正如你将看到的,太长了(我用这种方式构建了 66 个不同的新数据集,所以它没有任何意义)我想知道如何缩短它。我做了一些试验(plyr,...)但没有真正成功。这是我所做的:

# For the 1st year, groups of 2 obs
newmatrix <- data.frame(t(combn(unique(data$obs[data$year==1]), 2)))
colnames(newmatrix) <- c("obs1", "obs2")
newmatrix$name <- do.call(paste, c(newmatrix[c("obs1", "obs2")], sep = "_"))
# and the aggregation of var. using indexes, which I will skip here to save your time :)

为了说明,考虑到上述示例,我在第一年将获得的结果。 NA 是因为我只计算了 2 个值有效的值。并且仅适用于变量 1 和 3。更多,我做了总和,但它可以是任何其他可能的函数:

  order obs1 obs2 year var1 var3
1     1    1    3  1_3   42   NA
2     2    1    6  1_6   37   NA
3     3    1    7  1_7   NA   NA
4     4    3    6  3_6   15   NA
5     5    3    7  3_7   NA   NA
6     6    6    7  6_7   NA   NA

第3年第2行同类型矩阵:

  order obs1 obs2 year var1 var3
1     1    1    3  1_3   NA 3762
2     2    1    6  1_6   NA 2868
.......... etc ............

希望我解释清楚了。预先感谢您提供有关如何更有效地执行此操作的提示。

我会使用 split-apply-combine 按年份拆分,找到所有组合,然后再组合回去:

do.call(rbind, lapply(split(data, data$year), function(x) {
  p <- combn(nrow(x), 2)
  data.frame(order=paste(x$order[p[1,]], x$order[p[2,]], sep="_"),
             obs1=x$obs[p[1,]],
             obs2=x$obs[p[2,]],
             year=x$year[1],
             var1=x$var1[p[1,]] + x$var1[p[2,]],
             var2=x$var2[p[1,]] + x$var2[p[2,]],
             var3=x$var3[p[1,]] + x$var3[p[2,]])
}))
#     order obs1 obs2 year var1 var2 var3
# 1.1  3_33    1    3    1   42  802   NA
# 1.2  3_78    1    6    1   37  650   NA
# 1.3  3_93    1    7    1   NA   NA   NA
# 1.4 33_78    3    6    1   15  276   NA
# 1.5 33_93    3    7    1   NA   NA   NA
# 1.6 78_93    6    7    1   NA   NA   NA
# 2.1  4_34    1    3    2   43  926 3730
# 2.2  4_79    1    6    2   38  764 2681
# 2.3  4_94    1    7    2   37  775 2632
# 2.4 34_79    3    6    2   15  312 1641
# 2.5 34_94    3    7    2   14  323 1592
# 2.6 79_94    6    7    2    9  161  543
# 3.1  5_35    1    3    3   NA  920 3762
# 3.2  5_80    1    6    3   NA  754 2869
# 3.3  5_95    1    7    3   NA  732 2576
# 3.4 35_80    3    6    3   15  318 1893
# 3.5 35_95    3    7    3   13  296 1600
# 3.6 80_95    6    7    3    8  130  707

这使您能够非常灵活地组合一年内的观察数据对 --- x[p[1,],] 表示每对中第一个元素的特定年份数据,x[p[2,],]表示每对中第二个元素的特定年份数据。您可以 return 特定年份的数据框与成对数据的任意组合,并且特定年份的数据框与 do.callrbind 组合成一个最终数据框。