如何以编程方式向 R 中的交互函数提供用户输入(特别是在 totalcensus 包中)
How to supply user input programmatically to an interactive function in R (specifically in the totalcensus package)
我正在编写一个 R 脚本,它具有一些交互功能,可以停止代码以等待用户输入。我需要脚本 运行 完全自动化,以便 Travis-CI 可以独立构建它。我如何以编程方式提供用户输入,以便代码 运行 连续而不是停止交互输入?
具体来说,我在 R 中使用 totalcensus
包中的 read_acs5year
函数,当我 运行 此代码时:
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。
根据@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)
}
然后使用这个 nee 函数代替 read_acs5year
。它会立即自动下载,无需等待任何用户输入。
get_data(
year = 2012,
states = "AL",
table_contents = "B01003",
summary_level = "tract",
with_margin = TRUE
)
我正在编写一个 R 脚本,它具有一些交互功能,可以停止代码以等待用户输入。我需要脚本 运行 完全自动化,以便 Travis-CI 可以独立构建它。我如何以编程方式提供用户输入,以便代码 运行 连续而不是停止交互输入?
具体来说,我在 R 中使用 totalcensus
包中的 read_acs5year
函数,当我 运行 此代码时:
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。
根据@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)
}
然后使用这个 nee 函数代替 read_acs5year
。它会立即自动下载,无需等待任何用户输入。
get_data(
year = 2012,
states = "AL",
table_contents = "B01003",
summary_level = "tract",
with_margin = TRUE
)