在R中如何通过带参函数批量生成data.table并存入列表?
错误原因说明
你之前的lapply写法有两个问题:
- 把需要遍历的序列
1:3包裹成了列表,相当于lapply仅遍历1次,传入的参数是完整的1:3向量,而非逐个传入1、2、3 - 没有正确匹配参数顺序:lapply默认将遍历的值传递给自定义函数的第一个参数,而你的
create_dt第一个参数是tables_vector,所以参数完全匹配错误,导致运行失败
简化场景解决方案
不需要修改原有自定义函数,直接在lapply中套一层匿名函数指定参数即可,得到的结果和你手动拼接的列表完全一致:
# 单向量批量生成dt列表 dt_list <- lapply(1:length(tables_vector_1), function(x) create_dt(tables_vector = tables_vector_1, i = x))
如果需要批量处理多个业务分组的向量,可以把所有向量先汇总到一个命名列表中,嵌套一层lapply即可:
# 按业务分组汇总所有向量,命名方便后续识别 all_vec_list <- list( 用途1 = tables_vector_1, 用途2 = tables_vector_2 # 其余分组按需追加 ) # 批量生成所有分组的dt列表,返回嵌套列表:第一层为业务分组,第二层为分组内每个元素的dt all_dt_list <- lapply(all_vec_list, function(current_vec) { lapply(1:length(current_vec), function(idx) create_dt(tables_vector = current_vec, i = idx)) })
实际业务场景适配方案
原有函数直接复用方案
和简化场景逻辑完全一致,不需要修改你现有的import_data函数即可直接使用:
# 单分组批量拉取数据示例,以vector1为例 vector1_res <- lapply(1:length(vector1), function(x) import_data(tables_vector = vector1, i = x)) # 全部分组批量拉取 all_vec_list <- list( 用途1 = vector1, 用途2 = vector2 # 其余分组按需追加 ) all_import_res <- lapply(all_vec_list, function(current_vec) { lapply(1:length(current_vec), function(idx) import_data(tables_vector = current_vec, i = idx)) })
效率优化方案
你原有函数每次调用都会新建、断开数据库连接,分组多的时候会产生不必要的性能开销,可以调整函数把数据库连接提到循环外:
# 修改后的导入函数,连接从外部传入 import_data_v2 <- function(tables_vector,i, con){ end <- Sys.time() start <- end - 7200 query <- sprintf("SELECT %s.timeutc, %s.scal AS %s FROM %s WHERE timeutc BETWEEN '%s' AND '%s' AND mode='General';", tables_vector[i],tables_vector[i],tables_vector[i], tables_vector[i],start,end) rs <- dbSendQuery(con, query) df <- fetch(rs, n = -1) dbClearResult(rs) return(as.data.table(df)) } # 调用示例:一次建连,拉完所有数据再断开 con <- dbConnect("PostgreSQL", dbname="db", host = "host", user=db_user, password=db_password) vector1_res <- lapply(1:length(vector1), function(x) import_data_v2(tables_vector = vector1, i = x, con = con)) dbDisconnect(con)
内容的提问来源于stack exchange,提问作者Meiqi
相关产品推荐
相关产品推荐

