简体   繁体   English

在R中使用While循环创建n个组合

[英]Create n Combinations Using While Loop in R

Starting with a data frame of City, Condition and Order Number, I'm trying to create n possible combinations of Order Numbers by City & Condition ([1], [2], [3], [1]&[2], [1]&[3], [2]&[3], [1]&[2]&[3]). 从城市,条件和订单号的数据帧开始,我试图按城市和条件创建n个可能的订单号组合([1],[2],[3],[1]&[2], [1]&[3],[2]&[3],[1]&[2]&[3])。

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

Splitting by City & Condition: 按城市和条件划分:

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)

I'm able to use a while() loop with "combn" as my container for n to get close to a combination solution, however I am unable to save the output to a list object in an acceptable format. 我可以使用带有“ combn”的while()循环作为n的容器来接近组合解决方案,但是我无法以可接受的格式将输出保存到列表对象。

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

The code above gets close by listing all of the single combinations, then the doubles followed by the triples for each City & Condition, but I can not figure out how to remove the NAs, close the holes and then save to a list object like below. 上面的代码通过列出所有单个组合来结束,然后为每个“城市和条件”列出双打,然后是三联,但是我无法弄清楚如何删除NA,关闭孔,然后保存到如下所示的列表对象。

The desired final solution should look like the following: 所需的最终解决方案应如下所示:

[[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"

Thank you for taking a look and any help you can offer. 感谢您查看并提供任何帮助。

You can use dplyr to get a data.frame of lists: 您可以使用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]>

The newdat$lists column now has all your subsamples of each level of City:Condition in a list. 现在, newdat$lists列在列表中具有City:Condition的每个级别的所有子样本。

To get it in the same format as your desired output, we need to do a little list wrangling: 要以与所需输出相同的格式获取它,我们需要做一些清单整理:

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

EDIT: As a function: 编辑:作为功能:

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())}))) 
}

eg: 例如:

lister(dat, 2)

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

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