【问题标题】:sapply, lappy, function (x), RODBC, SQLServersapply、lapply、函数 (x)、ODBC、SQL Server
【发布时间】:2014-02-11 17:09:58
【问题描述】:

我想使用 apply 函数自动绘制 SQL Server 上大约 30 个表中包含的数据,但它不起作用。有没有更好的编码方式?

我想要什么:

  1. 使用 RODBC 建立与 SQL Server 的连接 --- 这工作正常
  2. 读取每个表格 --- 这也可以正常工作,例如读取到 df
  3. 排除系统 ID 字段和字符字段 --- 不起作用
  4. 在每个表中绘制数值字段 --- 在另一个循环中工作
  5. 将绘图写入 pdf,每个表格一个,每个表格字段一个图形 --- 在另一个循环中工作

SQL Server 表结构示例

  bSystemId cSystemId lengthdecimal heightquantity desc
1      2218        58            22            184    a
2      2219        58            22            109    b
3      2220        58            22            103    c
4      2221        58            22            192    d

循环代码:

t<-sqlTables(channel, tableType ="TABLE")  # create list
t1<-list(t[,3])                            #limit list to table names only

lapply(t1,function (x)   
   {
     a<-sqlFetch(channel,x,max=20)             
     a1<-a[sapply(a,is.numeric)]             
     varlist<-names(a[,!grepl("SystemId",(a1))]) 
     pdf(file=(paste(x,".pdf")) )
     figures<-lapply(varlist,function(y) 
         {
         plot(data=a, a[,1],a[,y], xlab=names(a[1]), ylab=as.name(y))
         })
dev.off()  
   })

对于特定情况,代码有效,但不适用于循环,即,

t1<-as.data.frame(sqlFetch(channel,"tbl1"))
a<-head(t1[sapply(t1,is.numeric)])
b<-a[,!grepl("SystemId",names(a))]

感谢任何cmets。

对于那些想要一个工作示例的人,使用原始代码和 dfs 而不是从 SQL Server 读取:

bSystemId<-seq(2218,2221,1)
cSystemId<-rep(58,4)
lengthdecimal<-rep(22,4)
heightquantity<-sample((100:220),4)
desc<-c("a","b","c","d")
t<-data.frame(bSystemId,cSystemId,lengthdecimal,heightquantity,desc)
s<-t*1.3

t1<-("s","t")                   
lapply(t1,function (x)   
   {
     a<-x  
     a1<-a[sapply(a,is.numeric)]             
     varlist<-names(a[,!grepl("SystemId",(a1))]) 
     pdf(file=(paste(x,".pdf")) )
     figures<-lapply(varlist,function(y) 
         {
         plot(data=a, a[,1],a[,y], xlab=names(a[1]), ylab=as.name(y))
         })
dev.off()  
   })

更新:

cmets 正在提供帮助。现在上面的主要代码块产生了这个错误: plot.window(...) 中的错误:需要有限的“ylim”值 另外:有50个或更多的警告(使用warnings()查看前50个)

更新 #2:

NA 正在影响情节陈述。更新代码:

 t<-sqlTables(channel, tableType ="TABLE")  # create list
 t1<-list(t[,3])                            

 lapply(t1,function (x)   
  {
    a<-sqlFetch(channel,x)
    ab<-a[is.na(a)]<- (-1)
    a1<-ab[sapply(ab,is.numeric)]
    varlist<-names(a1[,!grepl("SystemId",names(a1))])
    pdf(file=(paste(x,".pdf")) )
    figures<-lapply(varlist,function(y) 
         {
        (plot(a[,1],a[,y], xlab=names(a[1]), ylab=as.name(y)))
         })
 dev.off()  
  })

更新 #3

这是最终版本,包括用于排除 SQL Server 上某些系统表的过滤器。在 apply 函数中似乎可以使用或不使用 fixed = T。

 t<-sqlTables(channel, tableType ="TABLE")        
 t1<-list(t[,3]) 
 t1<-t1[[1]][-c(16,18:22)]                           

 lapply(t1,function (x)   
   {
     a<-sqlFetch(channel,x, max=200)                     
     ab<-(a[sapply(a,is.numeric)])      
     a1<-ab[is.na(ab)]<- (-1)   
     varlist<-names(ab[,!grepl("SystemId",names(ab))])
     pdf(file=(paste(x,".pdf")) )
     figures<-lapply(varlist,function(y) 
         {
         (plot(ab[,1],ab[,y], xlab=names(ab[1]), ylab=as.name(y)))
         })
 dev.off()  
    })

【问题讨论】:

  • 请添加一个可重现的例子。
  • varlist 将是一个逻辑向量,如果有的话,而不是我怀疑你想要的变量名列表。
  • 另外你不要将sqlFetch 的输出分配给任何东西
  • 这两个更正可能已修复它。现在就试试吧。
  • 现在我得到一个绘图窗口错误/需要有限 ylim 值错误和 50 个警告。更改摘要:1. sqlFetch 的分配输出,2. 为 varlist 语句添加了括号,3. 为 varlist 语句添加了“名称”(传递给 plot 语句)。我会继续努力的。感谢任何进一步的 cmets。

标签: r function loops sapply


【解决方案1】:

不知道你在哪里,但这个的变体对我有用:

lapply(t1,function (x)   
{
  a  <-sqlFetch(channel,x,max=20)             
  a1 <-a[sapply(a,is.numeric)]             
  varlist<-names(a[,!grepl("SystemId",names(a),fixed=T)]) 
  pdf(file=(paste(x,".pdf")) )
  figures<-lapply(varlist,function(y) 
  {
    plot(a[,1],a[,y], xlab=names(a[1]), ylab=as.name(y))
  })
  dev.off()  
})

由于sqlFetch,我无法完全按原样运行此程序,但基本上我发现您的原始代码存在以下问题:

  1. grepl(...) 需要一个正则表达式作为第一个参数,您传递的是一个简单的字符串。如果您使用fixed=T,则可以。
  2. 您需要将grepl(...) 应用于a 的列名,而不是“(a1)”。
  3. 您对 plot(...) 的调用不应包含 `data=...' 参数。

【讨论】:

  • 我会尝试修复 = T。我得到它来编写 pdf,但我收到一个错误:无效因子级别,生成 NA。--- 我可以通过使用来解决这个问题字符串AsFactors = FALSE?此外,我需要从绘图中排除字符字段和数字系统 ID 字段。如果我将 grepl() 应用于 a 而不是 a1 的列名,那会排除字符字段吗?
  • 您的代码针对每个非 systemId 字段绘制 a[,1],即 bSystemId 字段。那你是什么意思你想排除它?
  • 目的是使用 'a' 中的第一个字段作为图中的 x 变量,然后仅生成一个列表观察值——没有字符数据,没有系统 ID,并将它们用作 y多变的。所以这就是我使用'a1'的原​​因。否则,不清楚如何在一种情况下使用系统 ID,而在另一种情况下则不然。
  • 所以上面的代码应该可以工作。在对grepl(...) 的调用中使用fixed=T 将导致varlist 只有那些列 包含字符串"SystemId"
猜你喜欢
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
相关资源
最近更新 更多