使用 R 在数据帧列表中查找模式

Finding patterns in a list of dataframes using R

我有一个数据帧列表 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} 使得当添加到给定观察中的每个数字时,该观察变得等同于另一个。例如,考虑 L 的前 2 个元素并让 x=2,然后将 x 添加到 L 的第一个元素产生:

> 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 的元素,并根据 "the number of members" 对组进行排序。因此,在此处的示例中,我想检测 L[[1]]L[[2]] 在一个组中,并且这是成员最多的组,其次是下一组,在此示例中仅包含L[[3]]。我是 R 的新手,如有任何指导,我们将不胜感激!

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

让我们将代表定义为等价 class 中以“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

现在我们可以定义组了,在你的例子中有两个组。我们称它们为 group1group2:

## 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),您可以计算每个组的成员数。