我试图从列表中找到所有组合(不是排列,顺序并不重要),每个组合的结构都有各种限制。我知道combn()会做一个简单列表的技巧,我尝试使用sample(),但我的需求更复杂。
我的数据框有三列,名称,类型,成本。我希望找到7个集合中的所有可能的名称组合(所以7个名称),其中一个是类型1,三个是类型2,其余是类型3,总成本小于设置变量。
我完全不知道如何做到这一点,我甚至不确定R是否是正确的语言。我应该尝试使用一些嵌套的if语句进行for循环吗?
> dput(head(sample))
structure(list(Name = structure(c(6L, 8L, 4L, 9L, 2L, 5L), .Label = c("Amber",
"Cyndi", "E", "Eric", "Hannah", "Jason", "Jesse", "Jim ", "Lisa",
"Lucy", "Matt", "Ryan", "Tat"), class = "factor"), Type = c(2L,
3L, 3L, 1L, 3L, 3L), Cost = c(6000L, 6200L, 9000L, 2000L, 8000L,
4500L)), .Names = c("Name", "Type", "Cost"), row.names = c(NA,
6L), class = "data.frame")
和我的sessionInfo()
> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-apple-darwin10.8.0 (64-bit)
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] plyr_1.8.1 ggplot2_1.0.0 dplyr_0.2
loaded via a namespace (and not attached):
[1] assertthat_0.1 colorspace_1.2-4 digest_0.6.4 grid_3.1.1 gtable_0.1.2 MASS_7.3-33
[7] munsell_0.4.2 parallel_3.1.1 proto_0.3-10 Rcpp_0.11.2 reshape2_1.4 scales_0.2.4
[13] stringr_0.6.2 tools_3.1.1
示例数据:
Name Type Cost
Jason 2 6000
Jim 3 6200
Eric 3 9000
Lisa 1 2000
Cyndi 3 8000
Hannah 3 4500
E 2 7200
Matt 1 3200
Jesse 3 1200
Tat 3 3200
Ryan 1 5600
Amber 2 5222
Lucy 2 1000
如果总费用设置为60k,则可能有一种组合:
Lisa,Jason,Amber,Lucy,Tat,Jesse,Hannah
这是一个可能的组合,因为Lisa是1型,Jason,Amber和Lucy是2型,其余3个是3型,所有7的总成本低于60k。另一种可能的组合是:
Ryan,Jason,Amber,Lucy,Tat,Jesse,HannahRyan已将Lisa替换为第一组合中的1型。成本仍然低于60k。
我试图在上述条件成立的情况下获得所有可能的组合。
答案 0 :(得分:1)
使用循环的一种可能的解决方案(可能不是最有效的):
# Example data
Name <- c('Jason', 'Jim','Eric', 'Lisa', 'Cyndi', 'Hanna','Jon','Matt',
'Jerry','Emily','Mary','Cynthia')
Type <- c(2, 1, 3, 3, 2, 3, 3, 1, 2, 2, 3, 2)
Cost <- c(9200, 8200, 9000, 8700, 9100, 8900, 9800, 7800, 9600,
9300, 8100, 7800)
df <- data.frame(Name, Type,Cost)
v1 <- subset(df, Type==1)
v2 <- subset(df, Type==2)
v3 <- subset(df, Type==3)
# Get all combinations of desired size of subsets
m1 <- v1$Name
m2 <- combn(v2$Name, 3)
m3 <- combn(v3$Name, 3)
n1 <- length(m1)
n2 <- ncol(m2)
n3 <- ncol(m3)
# put combinations of subsets together
all.combs <- as.list(rep(NA, n1*n2*n3))
idx <- 1
for (i in 1:n1) {
for (j in 1:n2) {
for (k in 1:n3) {
all.combs[[idx]] <- c(as.character(m1[i]),
as.character(m2[,j]),
as.character(m3[,k]))
idx <- idx + 1
}
}
}
# Check for total cost < 60K
cond <- rep(NA, length(all.combs))
for (i in 1:length(all.combs)) {
sum <- 0
for (j in 1:7) {
sum <- sum + df$Cost[df$Name==all.combs[[i]][j]]
}
cond[i] <- sum < 60000
}
res <- all.combs[cond]
res