Как программно предоставить пользовательский ввод для интерактивной функции в R (в частности, в пакете totalcensus) - PullRequest
0 голосов
/ 14 июня 2019

Я пишу скрипт R, который имеет некоторые интерактивные функции, которые останавливают код для ожидания ввода пользователя. Мне нужно, чтобы скрипт был полностью автоматизирован, чтобы Travis-CI мог создавать его самостоятельно. Как мне ввести пользовательский ввод программно, чтобы код выполнялся непрерывно, а не останавливался для интерактивного ввода?

В частности, я использую функцию read_acs5year из пакета totalcensus в R, и когда я запускаю этот код:

acs_data_2008_2012_via_totalcensus <-
  read_acs5year(
    year = 2012,
    states = "AL",
    table_contents =
      "B01003",
    summary_level = "tract",
    with_margin = TRUE
)

выводит это на консоль:

Do you want to download data generated from decennial census 2010? This dataset is necessary for processing all summary files.
1: yes
2: no

Selection:

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

1 Ответ

1 голос
/ 16 июня 2019

По предложению @NelsonGon вы можете создать свою собственную версию функции, изменив параметр menu

get_data <- function(year,
                      states,
                      table_contents = NULL,
                      areas = NULL,
                      geo_headers = NULL,
                      summary_level = NULL,
                      geo_comp = "total",
                      with_margin = FALSE,
                      dec_fill = NULL,
                      show_progress = TRUE){

  ### check if the path to census is set ###

  if (Sys.getenv("PATH_TO_CENSUS") == ""){
    message(paste(
     "Please set up the path to downloaded census data",
     "following the instruction at",
     "https://github.com/GL-Li/totalcensus."
   ))
    return(NULL)
  }


  ### check whether to download data ###

  path_to_census <- Sys.getenv("PATH_TO_CENSUS")

  # check if need to download generated data from census2010
  generated_data <- paste0(path_to_census, "/generated_data")
  if (!file.exists(generated_data)){
    download_generated_data()
  } else {
    version_file <- paste0(generated_data, "/version.txt")
    if (!file.exists(version_file)){
      download_generated_data()
    } else {
      version = readChar(version_file, 5)
      if (version != "0.6.0"){
         download_generated_data()
      }
     }
   }

  # check whether to download acs5year data
  not_downloaded <- c()
  for (st in states){
     # only check for geoheader file
     if (!file.exists(paste0(
       path_to_census, "/acs5year/", year, "/g", year, "5",
       tolower(st), ".csv"
    ))){
       not_downloaded <- c(not_downloaded, st)
     }
   }
  if (length(not_downloaded) > 0){
      cat(paste0(
       "Do you want to download ",
       year,
       " ACS 5-year survey summary files of states ",
        paste0(not_downloaded, collapse = ", "),
       " and save it to your computer? ",
       "It is necessary for extracting the data."
     ))

     if (TRUE){
       download_census("acs5", year, not_downloaded)
     } else {
       stop("You choose not to download data.")
     }
    }


  ### read data ###

  if (is.null(summary_level)) summary_level <- "*"
     states <- toupper(states)    # allow lowcase input
  if (is.null(areas) + is.null(geo_headers) == 0){
     stop("Must keep at least one of arguments areas and geo_headers NULL")
   }

  # add population to table contents so that it will never empty, remove it
  # from table_contents if "B01003_001" is included.
   if (any(grepl("B01003_001", table_contents))){
       message("B01003_001 is the population column.")
   }

   table_contents <- table_contents[!grepl("B01003_001", table_contents)]
   table_contents <- c("population = B01003_001", table_contents) %>% unique()

   content_names <- organize_tablecontents(table_contents) %>% .[, name]
   table_contents <- organize_tablecontents(table_contents) %>%  .[, reference] %>%
     toupper()    # allow lowcase in reference input

   # turn off warning, fread() gives warnings when read non-scii characters.
   options(warn = -1)

    if (!is.null(areas)){
      dt <- read_acs5year_areas_(
            year, states, table_contents, areas, summary_level, geo_comp,
           with_margin, dec_fill, show_progress
      )
    } else {
       geo_headers <- unique(geo_headers)
       dt <- read_acs5year_geoheaders_(
         year, states, table_contents, geo_headers, summary_level, geo_comp,
         with_margin, dec_fill, show_progress
     )
    }

    setnames(dt, table_contents, content_names)

    if (with_margin){
        setnames(dt, paste0(table_contents, "_m"),
                paste0(content_names, "_margin"))
    }

    options(warn = 0)
    return(dt)
  }

и затем используйте эту функцию вместо read_acs5year. Теперь он будет автоматически загружен, не ожидая ввода пользователя.

 get_data(
     year = 2012,
     states = "AL",
     table_contents = "B01003",
     summary_level = "tract",
     with_margin = TRUE
 )
...