通过应用调用替换for循环返回列表列表而不是单个对象

时间:2017-02-13 12:14:42

标签: r lapply

需要从特定数据库表中获取列名,并在下一步中分配给要填充新数据的对象。

(使用postgresql,但你可以使用RBDMS yoy更喜欢。问题不是数据库,而是正确使用lapply)

这是完美的代码:

get_colNames_object <- function(x) {

            sqltext <- paste0("dbGetQuery(poscon, \"SELECT column_name FROM information_schema.columns WHERE table_name=\'", x,"\' AND table_schema=\'my_schema\'\")" )

            result <- eval(parse(text = sqltext))

            result <- unname(result$column_name)

            assign(x, result, envir = parent.frame()) 
          }

如果您使用一个表进行函数调用,这似乎有效。以这种方式返回对象:

      get_colNames_object("customers")

> customers

     [1] "id"                 "client_id"           "name"            "surname"

但.....在调用lapply时,我得到的是列表而不是单个对象:

tablelist <- c("customers", "sales")

lapply(tablelist, get_colNames_object)

[[1]]
[1] "id"                 "client_id"           "name"            "surname"              

[[2]]
[1] "id"                 "product_id"           "price"      "client_id"     

任何暗示为什么这不符合我的清单?预期的结果是关于列名的一堆对象。模式中的每个表都有一个。

2 个答案:

答案 0 :(得分:1)

我建议使用简单的循环而不是lapply。 这段代码对我有用:

for (t in tablelist) {

  text_to_parse <- paste0(t ," <- get_colNames_object(\'",t,"\')")

  eval(parse(text = text_to_parse))


}

答案 1 :(得分:1)

dbListFields中有一个函数DBI,可让您直接查询表的列名。我从dbListFields帮助页面扩展了有关使用lapply

的问题的示例
library(DBI)
library(RSQLite)

con <- dbConnect(RSQLite::SQLite(), ":memory:")

dbWriteTable(con, "mtcars", mtcars)
dbWriteTable(con, "mtcars2", mtcars)

table_list <- list("mtcars", "mtcars2")

t(sapply(table_list, dbListFields, conn = con))

结果:

[,1]        [,2]  [,3]  [,4]   [,5] [,6]   [,7] [,8]   [,9] [,10] [,11][,12] 
[1,] "row_names" "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am"  "gear" "carb"
[2,] "row_names" "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am"  "gear" "carb"