我有一些看起来像这样的数据:
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行的所有组合,包括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)
但我真的需要它来遍历数据框中的行。我感谢任何帮助。
答案 0 :(得分:0)
以下是一个解决方案,数据如下(您的输入数据仍然有点问题,我修改了代码以生成正确的数据):
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
调用中调用的外部函数。
答案 1 :(得分:0)
这里有你想要的固定数量的组合,而不是&#34; n&#34;组合数量。
expand.grid(c1, c2, c3, c4, c5, c6)
我建议使用此列表将c1,c2,c3 ..... cn放入列表中。
list <- mget(ls(pattern='^c\\d+'))
这将创建一个基于您的环境中的对象的列表,以字母&#34; c&#34;开头,为您的数据集标题更具体,以避免它吸收以&#34; c&#34开头的其他对象;或者你指定的任何东西。所以只需用你引用的对象名称的开头替换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的列表,我将不得不考虑这一点。很快就会回到这里。
我认为allPerms的一些组合功能是纯素包,而dplyr中的group_by包应该可以解决问题,但我必须看看。