2015-10-13 54 views
1

与市,条件和订单号的数据帧开始使用,我试图通过市&条件来创建订单数的Ñ可能的组合([1],[2] ,[3],[1] & [2],[1] & [3],[2] & [3],[1] & [2] & [3])。创建n个组合While循环中的R

library(gtools) 
set.seed(123) 
dat <- data.frame(City = c(rep("St. Louis", 3), rep("Chicago", 2)), 
       Condition = c(rep("A", 3), rep("B", 2)), 
       Order.No = round(runif(5,10,100),0)) 

的开裂市&条件:

dat_groups <- lapply(split(dat, list(dat$City, dat$Condition)), function(x) { 
    x$Order.No 
}) 

> dat_groups 
$Chicago.A 
numeric(0) 

$`St. Louis.A` 
[1] 36 81 47 

$Chicago.B 
[1] 89 95 

$`St. Louis.B` 
numeric(0) 

我能够使用while()循环使用“combn”作为我的ň容器亲近的组合解决方案,但是我无法以可接受的格式将输出保存到列表对象。

combn <- 4 
counter <- 0 
while (counter <= combn) { 
    counter <- counter + 1 
    temp <- lapply(dat_groups, function(x) { 
     n_obs <- length(x) 
     if(n_obs == 0) { 
      NA 
     } 
      if(n_obs > 0 & n_obs >= counter) { 
       combinations(n_obs, counter, x)  
      } else { 
       NA 
      } 
     }) 
print(temp) 
} 

$Chicago.A 
[1] NA 

$`St. Louis.A` 
    [,1] 
[1,] 36 
[2,] 47 
[3,] 81 

$Chicago.B 
    [,1] 
[1,] 89 
[2,] 95 

$`St. Louis.B` 
[1] NA 

$Chicago.A 
[1] NA 

$`St. Louis.A` 
    [,1] [,2] 
[1,] 36 47 
[2,] 36 81 
[3,] 47 81 

$Chicago.B 
    [,1] [,2] 
[1,] 89 95 

$`St. Louis.B` 
[1] NA 

$Chicago.A 
[1] NA 

$`St. Louis.A` 
    [,1] [,2] [,3] 
[1,] 36 47 81 
............... 
truncated 

上面的代码通过列出所有的单个组合的靠拢,然后双打其次是三元每个城市&条件,但我无法弄清楚如何去除港定居,关闭孔,然后保存到如下所示的列表对象。

所需的最终解决方案应该如下所示:

[[1]] 
[1] "36" 

[[2]] 
[1] "81" 

[[3]] 
[1] "47" 

[[4]] 
[1] "36" "81" 

[[5]] 
[1] "36" "47" 

[[6]] 
[1] "81" "47" 

[[7]] 
[1] "36" "81" "47" 

[[8]] 
[1] "89" 

[[9]] 
[1] "95" 

[[10]] 
[1] "89" "95" 

感谢您抽出一看,你可以提供任何帮助。列表中的条件:

回答

2

您可以使用dplyr获取列表的data.frame:

library(dplyr) 
newdat <- dat %>% group_by(City, Condition) %>% 
        summarise(lists = list(lapply(1:n(), 
          function(z){combinations(v=Order.No, r=z, n=n())}))) 
newdat 
Source: local data frame [2 x 3] 
Groups: City [?] 

     City Condition  lists 
    (fctr) (fctr)  (chr) 
1 Chicago   B <list[2]> 
2 St. Louis   A <list[3]> 

newdat$lists列现在有市的每个级别的所有子样本。

为了得到它在相同的格式,你想要的输出,我们需要做一个小名单扯皮:

unlist(lapply(unlist(newdat$lists, recursive = FALSE), 
       function(x){as.list(data.frame(t(x)))}), recursive = FALSE) 
$X1 
[1] 89 

$X2 
[1] 95 

$t.x. 
[1] 89 95 

$X1 
[1] 36 

$X2 
[1] 47 

$X3 
[1] 81 

$X1 
[1] 36 47 

$X2 
[1] 36 81 

$X3 
[1] 47 81 

$t.x. 
[1] 36 47 81 

编辑:作为一个功能:

lister <- function(data, numgroups){ 
    data %>% group_by(City, Condition) %>% 
     summarise(lists = list(lapply(1:min(numgroups, n()), 
             function(z){combinations(v=Order.No, r=z, n=n())}))) 
} 

如:

lister(dat, 2) 
+0

感谢您回复@jeremycg。不会使用n()总是导致为每个城市/条件组使用所有订单号码?这是我的问题的核心。我需要能够设置变量n并将其应用于每个组,而不管每个组有多少个订单号。即第一组有15个订单号码,n = 2,所以我只想看到所有1:2组合,而不是1:15组合。 – Brian

+0

当然,在这种情况下,可以将'n()'换成你想要的数字,或者用'function(numberofrepeats)....将函数全部包装到函数中,并用你的函数替换这两个'n()'变量 – jeremycg

+0

对不起,我对goup_by不熟悉,所以我在如何将代码包装到另一个函数中挣扎。我很确定它必须在函数()中,但有些if()else条件,因为如果给定组的Orders数少于_n_,它将会弹出。 – Brian