1

我有一个列表列表,其中包含以下 2 个变量:

> dist_sub[[1]]$zip
 [1] 901 902 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
[26] 929 930 931 933 934 935 936 937 938 939 940 955 961 962 963 965 966 968 969 970 975 981

> dist_sub[[1]]$hu
 [1]  4990    NA   168 13224    NA  3805    NA  6096  3884  4065    NA 16538    NA 12348 10850    NA
[17]  9322 17728    NA 13969 24971  5413 47317  7893    NA    NA    NA    NA    NA   140    NA     4
[33]    NA    NA    NA    NA    NA 13394  8939    NA  3848  7894  2228 17775    NA    NA    NA



> dist_sub[[2]]$zip
 [1] 921 934 952 956 957 958 959 960 961 962 965 966 968 969 970 971

> dist_sub[[2]]$hu
 [1] 17728   140  4169 32550 18275    NA 22445     0 13394  8939  3848  7894  2228 17775    NA 12895

有没有办法删除重复项,如果邮政编码出现在一个列表中,则根据特定标准从其他列表中删除?

示例:邮政编码 00921 出现在上面的两个列表中。我只想将其保留在 hu(住房单元)总和最低的列表中。在此,我只想将邮政编码 00921 保留在第二个列表中,因为列表 2 中的总和为 162,280,而列表 1 中的总和为 256,803。

很感谢任何形式的帮助。

4

1 回答 1

2

这是您的问题的模拟数据集,以便其他人也可以使用它。

dist_sub <- list(list("zip"=1:10,
                      "hu"=rnorm(10)),
                list("zip"=8:12,
                      "hu"=rnorm(5)),
                list("zip"=c(1, 3, 11, 7),
                      "hu"=rnorm(4))
                )

这是我能够提出的解决方案。我意识到循环确实是执行此操作的更清洁的方法:

do.this <- function (x) {
  for(k in 1:(length(x) - 1)) {
    for (l in (k + 1):length(x)) {
      to.remove <- which(x[[k]][["zip"]] %in% x[[l]][["zip"]])
      x[[k]][["zip"]] <- x[[k]][["zip"]][-to.remove]
      x[[k]][["hu"]] <- x[[k]][["hu"]][-to.remove]
    }
  }
  return(x)
}

这个想法非常简单:对于每组 zip,我们不断删除在其后面的任何一组中重复的元素。我们这样做直到倒数第二组,因为最后一组将在其之前的任何内容中都没有重复。

使用您拥有的标准的解决方案,即最低总和hu可以使用上面的函数轻松实现。您需要做的是dist_sub通过总和重新排序列表,hu如下所示:

sum_hu <- sapply(dist_sub, function (k) sum(k[["hu"]], na.rm=TRUE))
dist_sub <- dist_sub[order(sum_hu, decreasing=TRUE)]

现在你已经dist_sub排序了,sum_hu这意味着对于每个集合,它之前的集合都更大sum_hu。因此,如果值ij(i < j) 处的集合具有a共同的值,a则应从ith 元素中删除。这也是该解决方案的作用。你认为这有意义吗?

PS:我调用该函数do.this是因为我通常喜欢编写通用解决方案,而这是一个非常具体的问题,尽管是一个有趣的问题。

于 2013-07-16T22:33:18.713 回答