【发布时间】:2020-01-28 17:55:34
【问题描述】:
我有一个 Docker 容器,它设置为每周通过 Airflow DAG 运行一个 R 脚本。 DAG 有 3 个事件 - 1 个位于 Docker 代码的上游,该代码从多个数据库获取数据,计算各种特征,然后将数据写入 S3。该脚本从 S3 存储桶中读取数据,格式化数据帧,运行模型对记录进行评分,然后将数据写回 S3。最后是下游代码,用于格式化输出,以便可以将其加载到 Salesforce 中。当我在 12 月编写和构建它时,该脚本在测试时工作。最近运行多次失败,报错码:
Error in as.character(x) :
cannot coerce type 'closure' to vector of type 'character'
Calls: %>% ... mutate_impl -> ymd -> .parse_xxx -> unlist -> lapply -> FUN
Execution halted
好的,这似乎意味着它作为字符读取的日期在格式化为日期时存在问题。由于“ymd”在链中,我相信它是下面 R 脚本中的 Lubridate 函数。
Docker 文件(下面的代码)利用具有 Tidyverse 的 R 映像,因为我的代码使用 Dplyr 和 Lubridate。我可能会在没有 Lubridate 的情况下使用基本函数来格式化日期,但下面会详细介绍
Docker 文件代码:
FROM rocker/tidyverse
RUN mkdir -p /model
RUN apt-get update -qq && apt-get install -y \
libssl-dev \
libcurl4-gnutls-dev
RUN R -e "install.packages('caret')"
RUN R -e "install.packages('randomForest')"
RUN R -e "install.packages('lubridate')"
RUN R -e "install.packages('aws.s3')"
EXPOSE 80
EXPOSE 8787
COPY / /
ENTRYPOINT ["Rscript", "account_health_scoring.R"]
R 脚本:由于一些识别信息和凭据,我必须排除前几行,但代码首先只是从文件中读取我的 S3 凭据。然后,此代码块运行并失败。下游有很多代码,但它们都在容器中起作用:
require("dplyr")
require("caret")
require("aws.s3")
require("randomForest")
require("lubridate")
#set credentials
Sys.setenv("AWS_ACCESS_KEY_ID" = "key",
"AWS_SECRET_ACCESS_KEY" = "key")
#read in model file
s3load("rf_gridsearch.RData", bucket = "account-model")
#read in data
data<-read.csv(text = rawToChar(get_object((paste0("account_health_data_",
gsub("-", "_", as.character(Sys.Date()),
fixed=TRUE),".csv")),
bucket = "account-health-model-input")),
stringsAsFactors = FALSE)%>%
mutate(period=ymd(period))%>%
mutate_if(is.integer,as.numeric)
2 mutate 行的原因是,尽管被格式化为 POSIX 时间戳,R 将日期强制转换为字符串并将浮点数强制转换为整数。也许我在 read.csv 中也遗漏了一些东西,或者有一个更好的函数可以正确读取数据,但这是我一直使用的。
问题:
错误消息指的是什么/我认为 YMD 函数是罪魁祸首是否正确?
如果是这样,我如何可能使用基函数重写我的代码以实现相同的目标并避免依赖包。
可能是包依赖关系吗?在查看日志时,情况似乎并非如此,因为 Lubridate 导入了几个基本功能/使用了几个。自从我编写并测试了这段代码以来,这个包还没有更新过。
【问题讨论】:
-
要求自动加载它们。日志确认包已加载并附加。我将编辑以显示此内容。
-
尝试只运行第一行代码,直到创建“数据”
data<-read.csv(text = rawToChar(get_object((paste0("account_health_data_", gsub("-", "_", as.character(Sys.Date()), fixed=TRUE),".csv")), bucket = "account-health-model-input")), stringsAsFactors = FALSE),然后得到str(data) -
这里的
ymd表示该列的格式为年月日,假设不是该格式,则需要更改 -
该列采用该格式。日期存储为 POSIX 时间戳,并且上游运行的数据清理脚本会去除时间戳,使其采用写入格式。