经过一段时间的努力,我希望有人可以帮我解决这个问题,对我来说这看起来很简单,但可能比我想象的更复杂:
我有一个包含三列的data.frame。前两个反映了五个变量的所有可能组合(1-5),最后一个"强度"组合。我查找了五行,其中包括Var1和Var2的所有值(因此值为1-5),并且在strength列中具有最高的总和。在下面的示例中,它是五行,强度为1000,因为它们具有最高的总和,并且前两列中给出了所有五个值(1-5)。
我如何最好地解决这个问题?有没有实现该任务的包?我现在发现了constrOptim()函数,我可以用它做吗?
创建示例数据帧的代码:
a <-cbind(expand.grid(seq(1,5,1),seq(1,5,1)),
strength = c(-11, 61, 230, 118, 156, 98, 169, 306, 6, -54,
207, -32, 27, 128, 101, 19, -18, 32, 153, 14,
63, 136, 165, 73, 35))
a <- a[order(a$strength, decreasing=T),]
启动数据集:
Var1 Var2 strength
3 2 306
3 1 230
1 3 207
2 2 169
3 5 165
5 1 156
4 4 153
2 5 136
4 3 128
4 1 118
5 3 101
1 2 98
4 5 73
1 5 63
2 1 61
5 5 35
3 4 32
3 3 27
1 4 19
5 4 14
4 2 6
1 1 -11
2 4 -18
2 3 -32
5 2 -54
不理想的结果:
Var1 Var2 strength
3 2 306
3 1 230
1 3 207
2 2 169
3 5 165
期望的结果:
Var1 Var2 strength
3 2 306
1 3 207
5 1 156
4 4 153
2 5 136
答案 0 :(得分:1)
在Var1
和Var2
列之间考虑一系列aggregation和merges:
# MERGE MAX AGGREGATES WHERE Var COL ARE EQUAL AND NOT EQUAL
mergedf1 <- merge(aggregate(strength ~ Var1, data=a[a$Var1==a$Var2,], FUN=max),
a, by=c("Var1", "strength"))
mergedf2 <- merge(aggregate(strength ~ Var1, data=a[a$Var1!=a$Var2,], FUN=max),
a, by=c("Var1", "strength"))
# STACK RESULTS
mergedf <- rbind(mergedf1, mergedf2)
# FINAL MAX AGGREGATION AND MERGE
final <- merge(aggregate(strength ~ Var2, data=mergedf, FUN=max),
mergedf, by=c("Var2", "strength"))
final <- final[,c("Var1", "Var2", "strength")] # SORT COLUMNS
final <- final[with(final, order(-strength)),] # SORT ROWS
# REMOVE TEMP OBJECTS
rm(mergedf1, mergedf2, mergedf)
答案 1 :(得分:1)
我不确定所提出的解决方案是否最有效,但不知何故我觉得我们必须遍历整个数据集才能找到唯一的对(例如将(Var1 = 2, Var2 = 5, strength = 136)
的值更改为{{1}为了找到唯一的对,我使用了apply函数。首先让我们重新创建输入:
(Var1 = 2, Var2 = 5, strength = 1)
现在我准备一个空矩阵,我将在第一列中保留a <-cbind(expand.grid(seq(1,5,1),seq(1,5,1)),
strength = c(-11, 61, 230, 118, 156, 98, 169, 306, 6, -54,
207, -32, 27, 128, 101, 19, -18, 32, 153, 14,
63, 136, 165, 73, 35))
a <- a[order(a$strength, decreasing=T),]
,在第二列中保留Var1
,在第三列保留Var2
。
strength
接下来,我编写了一个函数,它将从有序数据集V <- matrix(nrow = 5, ncol = 3)
中获取一行,检查a
和Var1
是否唯一,如果是,则会存储强度。
Var2
现在我在mf <- function(x){
if( !(x[1] %in% V[,1]) & !(x[2] %in% V[,2])) {
i <- x[1]
V[i,1] <<- x[1]
V[i,2] <<- x[2]
V[i,3] <<- x[3]
}
}
的每一行上应用该函数:
a
所需的值存储在矩阵apply(a, 1, mf)
:
V
有时,尽管不需要遍历完整数据集(如在给出的示例中),但是一旦找到唯一对,我们希望能够打破循环。为此,我们可以使用V
[,1] [,2] [,3]
[1,] 1 3 207
[2,] 2 5 136
[3,] 3 2 306
[4,] 4 4 153
[5,] 5 1 156
循环。这是代码:
for
希望这会有所帮助,或至少会带来改善。