多循环创建组合列表

时间:2019-02-21 22:55:27

标签: r loops combinations

我试图使用循环来创建组合列表,但是我没有得到所有的迭代,并且它生成的数量比我预期的要少。 我正在使用的代码:

base = "http://sigtap.datasus.gov.br/r"
    codes = list(304020060, 304050083, 304010308, 304070017, 304010081, 304020184, 304050040, 304040045, 304010308, 304030074, 304020338, 304020079, 304040134, 304010081)      #14 different codes 
    month = c("01", "02", "03", "04","05","06","07","08", "09", "10", "11","12")
    year = c(2015:2018)


  for (i in base) {
    for(j in codes){
      for (k in month) {
        for (l in year) {
          html <-  paste(i, j, k, l, sep = "/" )
    }}}}

我原本希望获得一条代码,月份和年份的记录(大约670条不同记录),但是我只有14条记录:

 [1] "http://sigtap.datasus.gov.br/app/sec/304020060/12/2015"
 [2] "http://sigtap.datasus.gov.br/app/sec/304050083/12/2016"
 [3] "http://sigtap.datasus.gov.br/app/sec/304010308/12/2017"
 [4] "http://sigtap.datasus.gov.br/app/sec/304070017/12/2018"
 [5] "http://sigtap.datasus.gov.br/app/sec/304010081/12/2015"
 [6] "http://sigtap.datasus.gov.br/app/sec/304020184/12/2016"
 [7] "http://sigtap.datasus.gov.br/app/sec/304050040/12/2017"
 [8] "http://sigtap.datasus.gov.br/app/sec/304040045/12/2018"
 [9] "http://sigtap.datasus.gov.br/app/sec/304010308/12/2015"
[10] "http://sigtap.datasus.gov.br/app/sec/304030074/12/2016"
[11] "http://sigtap.datasus.gov.br/app/sec/304020338/12/2017"
[12] "http://sigtap.datasus.gov.br/app/sec/304020079/12/2018"
[13] "http://sigtap.datasus.gov.br/app/sec/304040134/12/2015"
[14] "http://sigtap.datasus.gov.br/app/sec/304010081/12/2016"

任何帮助都会很棒!

谢谢!

4 个答案:

答案 0 :(得分:3)

您可以使用do.call

加快代码速度
out <- do.call(paste, c(base, expand.grid(codes, month, year), sep = "/"))
head(out)
#[1] "http://sigtap.datasus.gov.br/r/304020060/01/2015"
#[2] "http://sigtap.datasus.gov.br/r/304050083/01/2015"
#[3] "http://sigtap.datasus.gov.br/r/304010308/01/2015"
#[4] "http://sigtap.datasus.gov.br/r/304070017/01/2015"
#[5] "http://sigtap.datasus.gov.br/r/304010081/01/2015"
#[6] "http://sigtap.datasus.gov.br/r/304020184/01/2015"

检查元素数

length(out)
#[1] 672

由于base是一个常量,因此无需将其放入expand.grid

答案 1 :(得分:2)

这很好用,请记住保存每个迭代而不覆盖它。

base = "http://sigtap.datasus.gov.br/r"
    codes = list(304020060, 304050083, 304010308, 304070017, 304010081, 304020184, 304050040, 304040045, 304010308, 304030074, 304020338, 304020079, 304040134, 304010081)      #14 different codes 
    month = c("01", "02", "03", "04","05","06","07","08", "09", "10", "11","12")
    year = c(2015:2018)
    html=list()
    iteration=1


  for (i in base) {
    for(j in codes){
      for (k in month) {
        for (l in year) {
          html[[iteration]] <-  paste(i, j, k, l, sep = "/" )
          iteration<-iteration+1

    }}}}

 > length(html)
[1] 672

答案 2 :(得分:1)

在我看来,您正在尝试从向量创建html字符串列表。这可以很简单地完成。

从基础上,我们可以使用函数--dry-run

创建具有所有组合的矩阵
expand.grid

在此之后,我们可以使用在第一个边距上应用的apply函数创建每个字符串(combs <- expand.grid(base, codes, month, year) 与遍历矩阵的行相同)。对于每一行,我们希望执行与您的

相同的粘贴
MARGIN = 1

您完成了。基本上,apply函数代替了循环。请注意,我已将html <- apply(combs, MARGIN = 1, FUN = function(x)paste(x, collapse = "/")) 自变量替换为sep = "/"自变量。这是因为我粘贴了一个向量(collapse = "/"中的每一行)。因此,我正在折叠矩阵,而不是消除分离。

答案 3 :(得分:1)

似乎您缺少html <- paste(...)中的索引。您拥有的方式,每次迭代都会覆盖之前的html

但是,如果您创建data.framedata.table,则会更清楚:

library(data.table)
Base = "http://sigtap.datasus.gov.br/r"
Code = c(304020060, 304050083, 304010308, 304070017, 304010081, 304020184,
          304050040, 304040045, 304010308, 304030074, 304020338, 304020079,
          304040134, 304010081)
Mnth = c(paste0(0, 1:9), 10:12)
Year = c(2015:2018)
Combinations <- data.table(base = rep("http://sigtap.datasus.gov.br", times = 14 * 12 * 4),
                           code = rep(Code, each = 12 * 4),
                           month= rep(Mnth, each = 14 * 4),
                           year = rep(Year, each = 14 * 12))
Combinations[, URL := paste0(base, code, month, year)]

这是个人喜好,但除非有必要,否则我尽量避免for循环。最好不要对对象和基本函数使用相同的名称。例如,month是一个从日期获取月份的函数。这就是我将basecodemonthyear重命名的原因。