繁体   English   中英

R所有可能的子组合

[英]R All possible sub-combinations

我有一些看起来像这样的数据:

basin <- c("Volta","Seine","Limpopo")
c1 <- c("BEN","BEL","SA")
c2 <- c("BURK","FRA","MOZ")
c3 <- c("IVC","LUX","ZIM")
c4 <- c("GHA","NA","BOTS")
c5 <- c("MALI","NA","NA")
c6 <- c("TOGO","NA","NA")
df <- data.frame(basin, c1, c2, c3, c4, c5, c6)

    basin  c1  c2  c3   c4   c5   c6
1   Volta BEN BUR IVC  GHA MALI TOGO
2   Seine BEL FRA LUX   NA   NA   NA
3 Limpopo  SA MOZ ZIM BOTS   NA   NA

每个盆地有k个国家。 例如,在第一行中,我需要生成5个国家的所有组合,4个国家的所有组合,依此类推。 第二行需要生成2个国家的所有组合,第三行需要3个国家和2个国家的所有组合。 然后,我想将这些子集添加为数据中的新行。

我尝试使用此功能:

    allSubs <- function(x, k) {
  if(k > length(x)) stop('k > length(x)')
  if(choose(length(x), k)==1){
    list(as.vector(combn(x, k)))
  } else {
    cbn <- combn(x, k)
    lapply(seq(ncol(cbn)), function(i) cbn[,i])
  }
}    

但是,只有在向它提供如下数据时,我才能使它工作:

allSubs(c('BEN','BURK','IVC','GHA','MALI','TOGO'),4)

但是我真的需要它来遍历数据帧中的行。 我感谢任何帮助。

这是一种使用数据的解决方案,如下所示(您的输入数据仍然有点问题,我修改了代码以生成正确的数据):

basin <- c("Volta","Seine","Limpopo")
c1 <- c("BEN","BEL","SA")
c2 <- c("BURK","FRA","MOZ")
c3 <- c("IVC","LUX","ZIM")
c4 <- c("GHA",NA,"BOTS")
c5 <- c("MALI",NA,NA)
c6 <- c("TOGO",NA,NA)
df <- data.frame(basin, c1, c2, c3, c4, c5, c6, stringsAsFactors = FALSE)

    basin  c1   c2  c3   c4   c5   c6
1   Volta BEN BURK IVC  GHA MALI TOGO
2   Seine BEL  FRA LUX <NA> <NA> <NA>
3 Limpopo  SA  MOZ ZIM BOTS <NA> <NA>

apply(df[, 2:7], 1, function(x) {l <- x[!is.na(x)]; sapply(seq(1:(length(l)-1)), function(y) combn(l, y))})

结果将是每行每个国家/地区代码的各种子组合。 希望这可以帮助。 当然,您可以将我曾经使用的“内联”函数拆分为您在apply调用中调用的外部函数。

这是您想要固定数量的组合,而不是“ n”个组合的数量。

expand.grid(c1, c2, c3, c4, c5, c6)

我建议使用此列表将c1,c2,c3 ..... cn放在列表中。

list <- mget(ls(pattern='^c\\d+'))

这会根据环境中以字母“ c”开头的对象创建一个列表,为数据集添加更具体的标题,以避免它使用以“ c”开头或由其指定的任何其他对象。 因此,只需将c替换为要引用的对象名称的开头即可。

expand.grid(list)

    c1  c2   c3   c4  c5   c6
1   BEN BURK IVC  GHA MALI TOGO
2   BEL BURK IVC  GHA MALI TOGO
3    SA BURK IVC  GHA MALI TOGO
4   BEN  FRA IVC  GHA MALI TOGO
5   BEL  FRA IVC  GHA MALI TOGO
6    SA  FRA IVC  GHA MALI TOGO
7   BEN  MOZ IVC  GHA MALI TOGO
8   BEL  MOZ IVC  GHA MALI TOGO
9    SA  MOZ IVC  GHA MALI TOGO
10  BEN BURK LUX  GHA MALI TOGO

...............................

723  SA BURK ZIM BOTS <NA> <NA>
724 BEN  FRA ZIM BOTS <NA> <NA>
725 BEL  FRA ZIM BOTS <NA> <NA>
726  SA  FRA ZIM BOTS <NA> <NA>
727 BEN  MOZ ZIM BOTS <NA> <NA>
728 BEL  MOZ ZIM BOTS <NA> <NA>
729  SA  MOZ ZIM BOTS <NA> <NA>

如果您想知道如何为一系列对象分配相似的名称,我建议您尝试使用assign函数。

这是一个例子。

for (i in 2:ncol(df)-1) {
  assign(paste("Combo",i,sep=""), df[, i+1])
}

如果您不喜欢对变量名进行硬编码,那可是值得深思的。

对于所有可能的1s,2s,3s,4s,5s,6s .... ns的列表,我将不得不考虑这一点。 很快会回到这个。

我在想将vegan包中的allPerms函数与dplyr中的group_by包结合起来可以解决问题,但是我必须要看一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM