【问题标题】:Chaining list of vectors向量链表
【发布时间】:2017-06-27 20:24:47
【问题描述】:

如果我有如下向量列表

list.x <- list(1:2, 1:3, 3:4, 5, 5:6)

有没有办法将每个列表元素替换为包含该元素可以配对的所有其他值的元素?

例如,第一个元素 (list.x[[1]]) 将替换为 1:4,因为元素 2 (list.x[[2]]) 显示 2 也与 3 配对,而元素 3 显示 3 也与 4 配对。

我想要达到的最终结果是这个列表

final.list <- list(1:4, 1:4, 1:4, 5:6, 5:6)

【问题讨论】:

  • 似乎是一个图论问题。 igraph 可能有一些东西。您的列表定义了边,并且您希望在每个连接的组件中找到节点。
  • 实际上,我什至建议this as a dupe。您只需要制作图形对象,在其上运行igraph::components,然后按照您的意愿格式化结果。
  • 谢谢,我需要了解图形对象。如果我的向量列表是字符向量列表,你知道这是否可行吗?
  • 我知道在数字列表和字符列表之间进行转换非常简单,所以没关系。如果是,只需转换。

标签: r tidyverse purrr


【解决方案1】:

我今天需要改变节奏,所以我决定尝试使用 base R 来回答这个问题。这里是:

首先,我创建了一个函数,如果它们相交,则合并两个向量,如果不相交,则简单地返回第一个向量:

expand.if.toucing <- function(vector1, vector2) {

  i = intersect(vector1, vector2);

  if (NROW(i) > 0) 
    union(vector1, vector2) 
  else 
    vector1;

}

然后我做了一个函数,将向量列表中的一个元素与另一个元素合并:

list.reduce <- function (lst) {

  for(v1 in 1:NROW(lst)) 
    for (v2 in 1:NROW(lst)) {

      if (v1 == v2) 
        next; 

      prevLength <- NROW(lst[[v1]]);

      lst[[v1]] <- expand.if.toucing(lst[[v1]], lst[[v2]]);

      newLength <- NROW(lst[[v1]]);

      if (newLength == prevLength)
        next;

      return(lst[-v2]);

    }

  lst;

}

在这之后,我做了一个函数来合并列表中所有可以合并的向量。这是一种原型聚类分析,所以我称之为聚类:

clusterize <- function (lst) {

  reduced = TRUE;

  while(reduced) {

    prevLength <- NROW(lst);

    lst <- list.reduce(lst);

    newLength <- NROW(lst);

    reduced <- prevLength != newLength;

  }

  lst;
}

现在只需将原始列表中的每个元素替换为其关联的集群即可:

replace.with.clusters <- function(lst, clusters) {

  for(l in 1:NROW(lst))
    for(c in 1:NROW(clusters)) {
      lst[[l]] <- expand.if.toucing(lst[[l]], clusters[[c]]);
      next;
    }

  lst;

}

你可以走了。两个主要功能是 clusterize 和 replace.with.cluster。像这样使用它们:

list.x <- list(1:2, 1:3, 3:4, 5, 5:6)
clusters <- clusterize(list.x);
replace.with.clusters(list.x, clusters);

# Outputs the following:
#
# [[1]]
# [1] 1 2 3 4
# 
# [[2]]
# [1] 1 2 3 4
# 
# [[3]]
# [1] 3 4 1 2
# 
# [[4]]
# [1] 5 6
# 
# [[5]]
# [1] 5 6

第三个元素的顺序与您的列表不同,但从您描述问题的方式来看,顺序并不真正相关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-03
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多