Все комбинации из кадра данных в R

Обновить

April 2019

Просмотры

923 раз

1

Я пытаюсь найти все комбинации (а не перестановки, порядок не имеет значения) из списка с различными ограничениями по структуре каждой комбинации. Я знаю combn () будет делать трюк для простого списка, и я попытался с помощью образца (), но моя потребность является более сложной.

У меня есть кадр данных, который имеет три колонки, название, тип, стоимость. Я хочу, чтобы найти все возможные комбинации имен в наборах 7 (около 7 имен), где один из которых имеет тип 1, три типа 2, а остальные типа 3, а общая стоимость меньше, чем множество переменных.

Я в полной потери для того, как сделать это, и я даже не уверен, R является правильным языком, чтобы сделать это. Должен ли я попробовать цикл с некоторыми вложенным, если заявления?

> 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:

Лиза, Джейсон, янтарный, Люси, Tat, Джесси, Ханна

Это одна из возможных комбинаций, а Лиза типа 1, Джейсон, Янтарный и Люси относятся к типу 2, а остальные три типа 3, а общая стоимость всего 7 ниже 60k. Другая возможная комбинация будет:

Райан, Джейсон, янтарный, Люси, Tat, Джесси, Ханна

Райан заменил Лизу в качестве 1-го типа из первой комбинации. Стоимость еще ниже 60к.

Я пытаюсь получить все возможные комбинации, где указанные выше условия являются истинными.

1 ответы

1

One possible solution using loops (maybe not the most efficient):

# 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