有没有一种简单的方法来检查R中每个变量之间的不等价性?

有没有一种简单的方法来检查R中每个变量之间的不等价性?,r,equality,R,Equality,在试图解决R中的以下逻辑问题时,我遇到了这种情况: 五名球衣号码为1、2、3、4、5的运动员参加比赛,他们得到的分数是球衣号码与他们完成比赛的排名的乘积;i、 例如,如果球衣号码为2的运动员获得第五名,他将获得2*5=10分。 身穿1号球衣的运动员没有以第4名和第5名的成绩完成比赛。 这5名运动员赛后总分为41分。 查找每个运动员完成比赛的排名 我用下面的代码解决了这个问题,并注意到如果一个人面对5个以上的变量,那么检查它们之间的不等价性可能会非常麻烦。例如,在10个变量中,它需要C10,2=4

在试图解决R中的以下逻辑问题时,我遇到了这种情况:

五名球衣号码为1、2、3、4、5的运动员参加比赛,他们得到的分数是球衣号码与他们完成比赛的排名的乘积;i、 例如,如果球衣号码为2的运动员获得第五名,他将获得2*5=10分。 身穿1号球衣的运动员没有以第4名和第5名的成绩完成比赛。 这5名运动员赛后总分为41分。 查找每个运动员完成比赛的排名

我用下面的代码解决了这个问题,并注意到如果一个人面对5个以上的变量,那么检查它们之间的不等价性可能会非常麻烦。例如,在10个变量中,它需要C10,2=45个比较

for (o in as.integer(1:5)) {
  for (t in as.integer(1:5)) {
    for (th in as.integer(1:5)) {
      for (f in as.integer(1:5)) {
         for (fi in as.integer(1:5)) {
if (o+2*t+3*th+4*f+5*fi == 41 && 
(o != 4 && o != 5) && 
# To check the following way in more complex cases is non-useful
((o!=t) && (o!=th) && (o!=f) && (o!=fi) && (t!=th) && (t!=f) && (t!=fi) && (th!=f) && (th!=fi) && (f!=fi))) {print(c(o,t,th,f,fi))}  
    }}}}}
#     o t th f fi
# [1] 2 5 4 3 1
有没有一种简单的方法来检查R中每个变量之间的不等价性

原始问题的来源:
这可能不是最节省内存的方法,因为我正在寻找所有可能的组合,但这里是我的初步想法,我将如何处理这一问题

#Get all possible combinations of ranks that can be taken
#Player 1 can take any place from 1:3, rest all can take any place from 1:5
df1 <- expand.grid(1:3, 1:5, 1:5, 1:5, 1:5)

#Find combinations where after multiplying by the scores sum of it is 41

df2 <- df1[colSums(t(df1) * 1:5) == 41, ]
#Or
#df2 <- df1[rowSums(t(t(df1) * 1:5)) == 41, ]

#Keep only the rows which have only unique combination of ranks
df2[!apply(df2, 1, anyDuplicated), ]

#    Var1 Var2 Var3 Var4 Var5
#209    2    5    4    3    1
您可以使用一个包排列:

library("permute")
d <- rbind(1:5, allPerms(5))
df <- as.data.frame(d)
names(df) <- c("o", "t", "th", "f", "fi")
subset(df, (o+2*t+3*th+4*f+5*fi == 41) &  (o != 4 & o != 5))

#> subset(df, (o+2*t+3*th+4*f+5*fi == 41) &  (o != 4 & o != 5))
#   o t th f fi
#48 2 5  4 3  1
以下是可用于n的其他值的变化:

n <- 5
d <- rbind(1:n, allPerms(n))
df <- as.data.frame(d)
names(df) <- paste0("r", 1:n)
subset(df, (d %*% (1:n) == 41) &  (r1 != 4 & r1 != 5))


Aaron Hayman的解决方案:

for (o in as.integer(1:5)) {
  for (t in as.integer(1:5)) {
    for (th in as.integer(1:5)) {
      for (f in as.integer(1:5)) {
         for (fi in as.integer(1:5)) {
if (o+2*t+3*th+4*f+5*fi == 41 && 
(o != 4 && o != 5) && 
( all( (1:5) %in% c(o,t,th,f,fi)) )) { # Trick
print(c(o,t,th,f,fi))}  
    }}}}}
# [1] 2 5 4 3 1

由于变量的可能值,即1,2,3,4,5,易于处理,并且可以通过%co,t,th,f,fi中的所有1:5%轻松进行检查,因此此解决方案效果良好。

我的解决方案是创建我自己的置换函数,因此实际上使用jogo建议的置换包可能更简单、更有效/更安全

这种排列利用了我在评论中提到的factoradic数的原理:

perm <- function(n, perm){
    pos=seq(n)
    res=integer(n)
    x=rev(seq(n))-1
    for(i in seq(n)){
        y  = 1 + perm%/%factorial(x[i])
        res[i] = pos[y]
        pos=pos[-y]
        perm = perm - factorial(x[i])*(y-1)
    }
    return(res)
}
ord = list()
for(i in seq(factorial(5))-1)
{
    p = perm(5,i)
    if(sum(p*1:5)==41 & p[1] < 4) ord =  append(ord,list(p))
}

ord
## [[1]]
## [1] 2 5 4 3 1

此解决方案使用嵌套for循环,因此它确实不太适合于R,但从算法角度来看可能很有趣。

co,t,th,f,fi中的所有1:5%将是一个足够的检查。但是你可能想读一读关于factoradic数字及其应用的书,如果你面对十个变量,那么你会写出所有的C10;2=45例?你似乎没有意识到这个问题的重要性!我认为问题在于你发布了一些代码,却没有解释你到底在做什么。此外,这个问题虽然你是为你的孩子提出的,但更像是一个家庭作业问题。这样的问题通常是离题的。使用as.integer是不必要的,因为1:5已经是一个整数向量了,也因为作为整数或浮点对arrithmetic没有任何影响,最后因为你将它们与double进行比较。@AaronHayman你的解在%co,t,th,f,fi中的所有1:5%似乎非常适合这种情况,但是,当我复制粘贴并将您的代码装载到相关位置时,我无法获得[1]2 5 4 3 1。我坐在空荡荡的一排。我正试图解决这个问题。为什么要进行双重转置?@NelsonGon因为,我们想要按列乘以1:5,我先进行转置,然后将数据帧重新转换为相同的结构,我再次进行转置。虽然可以通过使用colSums来避免,但是更新了它。@RonakShah Thx以获得expand.grid和apply的漂亮应用程序。你的解决方案很有教育意义。对于我8岁的孩子,我将暂时采用Aaron Hayman的解决方案。非常简单的答案。谢谢。您将只获得ord中的最后一个解决方案。我知道,但只有一个解决方案,我将进行编辑以使其更通用。我在编写后决定更改函数的名称,但没有更新调用。抢手货
perm <- function(n, perm){
    pos=seq(n)
    res=integer(n)
    x=rev(seq(n))-1
    for(i in seq(n)){
        y  = 1 + perm%/%factorial(x[i])
        res[i] = pos[y]
        pos=pos[-y]
        perm = perm - factorial(x[i])*(y-1)
    }
    return(res)
}
ord = list()
for(i in seq(factorial(5))-1)
{
    p = perm(5,i)
    if(sum(p*1:5)==41 & p[1] < 4) ord =  append(ord,list(p))
}

ord
## [[1]]
## [1] 2 5 4 3 1