sapply,lapply,function(x),ODBC,SQL Server

时间:2014-02-11 17:09:59

标签: r function loops sapply

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

我想要的是什么:

  1. 与RODBC建立SQL Server连接---这很好用
  2. 阅读每个表---这也可以正常工作,例如读到df
  3. 排除系统ID字段和字符字段---不起作用
  4. 在每个表中绘制数值字段---在另一个循环中工作
  5. 将图表写入pdf,每个表一个,每个表字段一个数字---在另一个循环中工作
  6. 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))]
    

    感谢您提出任何意见。

    对于那些想要一个工作示例的人,使用原始代码和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()  
       })
    

    更新

    评论有所帮助。现在上面的主要代码块会生成此错误:     plot.window(...)出错:需要有限的'ylim'值     另外:有50个或更多警告(使用警告()查看前50个)

    更新#2:

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

     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()  
        })
    

1 个答案:

答案 0 :(得分: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 = ...'参数。