聚合所有可能的唯一组合与 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.call
和 rbind
组合成一个最终数据框。
我正在尝试缩短一段代码,以使其更快、更容易修改。这是我的数据的一个简短示例。
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.call
和 rbind
组合成一个最终数据框。