0

我有一个数据框列表L,其中每个数据框由变量Var和一个由不同数字组成的观察值组成。每个观察中的每个数字都属于集合{1,2,3,4,5,11,12,13,14,15}L例如,可能看起来像:

> L 
[[1]]
                   Var
1 "3", "11", "1", "15", 

[[2]]
                   Var
1 "5", 13", "3", "12", 

[[3]]
                   Var
1 "4", "1", "2", "5", 

我要解决的问题如下。我想知道是否有一个正数x = {1,2,3,4,5},当添加到给定观察中的每个数字时,该观察变得等同于另一个。例如,考虑Land let的前 2 个元素x=2,然后添加xLyield 的第一个元素:

> L[[1]]
                   Var
1 "5", "13", "3", "17", 

数字 17 不满足上面定义的集合的条件。我希望以下约束适用于x. 让我们y在 obs 中表示一个数字。在数据框中L

if y + x > 15 then subtract 5
if 5 < y + x < 11 then subtract 5

具有这些约束的相同示例将产生:

> L[[1]]
                   Var
1 "5", "13", "3", "12", 

并且L[[1]]会变得等价于L[[2]]。在我的世界里,L[[1]]L[[2]]共享相同的模式。我想要做的是匹配L基于等效(在上述意义上)模式的元素,并根据“成员数量”对组进行排序。因此,在此处的示例中,我想检测L[[1]]L[[2]]在一个组中,并且这是具有最多成员的组,然后是下一个组,在此示例中仅包含L[[3]]. 我对 R 很陌生,任何指导将不胜感激!

4

1 回答 1

1

看起来您的“约束”定义了数学等价关系。这意味着您的组实际上是数学意义上的等价类,并且您可以为每个组定义一个唯一的代表。如果这样做,您可以通过比较它们的代表来轻松检查等价性(= 属于同一组的元素)。

让我们将代表定义为等价类中以“1”开头的元素,即,对于每个列表元素,我们在 中添加整数1:5,遵循您定义的约束,以便第一个元素等于一个。我们可以对列表中的每个元素执行此操作,L然后比较哪些元素具有相同的代表。

R中的实现:

让我们从您的清单开始L

L <- list(structure(list(Var = c("3", "11", "1", "15")), .Names = "Var", 
                row.names = c(NA, -4L), class = "data.frame"), 
        structure(list(Var = c("5", "13", "3", "12")), .Names = "Var", 
                row.names = c(NA, -4L), class = "data.frame"), 
        structure(list(Var = c("4", "1", "2", "5")), .Names = "Var", 
                row.names = c(NA, -4L), class = "data.frame"))

首先,我们通过将列表转换为数值向量列表来简化列表:

## Simplify list: convert to list of numerical vectors:
L2 <- lapply(L, function(x) as.numeric(x$Var))

> L2
[[1]]
[1]  3 11  1 15

[[2]]
[1]  5 13  3 12

[[3]]
[1] 4 1 2 5

然后我们定义执行加法的函数,遵循您的约束并找到每个元素的代表:

## Function to implement the addition rules:
addConstant <- function(myVec, constant){
    outVec <- myVec + constant  
    outVec <- ifelse(((outVec > 5) & (outVec < 11)) |(outVec > 15),
        outVec - 5, outVec) 
}

## Define representative of equivalence class as the one starting with a "1":
representativesList <- lapply(L2, function(myVec) addConstant(myVec, 6 - myVec[1]))

> representativesList 
[[1]]
[1]  1 14  4 13

[[2]]
[1]  1 14  4 13

[[3]]
[1] 1 3 4 2

现在我们可以定义组,在您的示例中有两个组。我们将调用它们group1并且group2

## Define groups: Unique representatives:
groupList <- unique(representativesList)
names(groupList) <- paste0("group", seq(along = groupList))

> groupList
$group1
[1]  1 14  4 13

$group2
[1] 1 3 4 2

最后,我们检查每个观察属于哪个组:

## Find group:
groupAffiliationVec <- vapply(representativesList, function(x){
            flagVec <- vapply(groupList, function(y, x) identical(x,y), logical(1), x)
            names(groupList[flagVec])           
        }, character(1))

> groupAffiliationVec
[1] "group1" "group1" "group2"

我们现在知道观察 1 和 2 属于同一组 ( group1) 并且观察 3 属于group1。使用table(groupAffiliationVec),您可以计算每个组的成员数。

于 2017-03-29T06:12:08.363 回答