为什么我的函数仅在其代码开头起作用?

时间:2018-12-14 12:27:08

标签: r function web-scraping screen-scraping

我在这里遇到的问题是,显然,该函数正在执行的唯一代码行是

library(rvest)
library(RCurl)

和  大家可以在代码结尾看到url <-paste("https://www.confaz.fazenda.gov.br/legislacao/boletim-do-icms/",estate,"/",year,month,sep="")

因此,我认为该函数无法将值附加到任何变量。你们能告诉我我该怎么解决吗?

我知道我可以使用调试更详细地了解正在发生的事情,但是我也遇到了困难。

icms_data <- function(estate, year, month){



  # Creating a data frame
  icms<- data.frame(NULL)

  library(rvest)
  library(RCurl)



  #downloading the webpage with the arguments from the function(estate, year and month)
  url <-paste("https://www.confaz.fazenda.gov.br/legislacao/boletim-do-icms/",estate,"/",year,month,sep="")
  #ignore token validation
  options(RCurlOptions = 
            list(capath = system.file("CurlSSL", 
                                      "cacert.pem", 
                                      package = "RCurl"), 
                 ssl.verifypeer = FALSE))

  y1<-getURL(url) 
  y <- read_html(y1)


  a<- y %>%
    html_nodes("#formfield-form-widgets-icms_primario div") %>%
    html_text()
  if(all.equal(a,character(0))==TRUE)
  {
    a=0
  } else
  {
    a<-substr(a,4,100)
    a = type.convert(a, na.strings = "NA", as.is = F, dec = ",",numerals = "no.loss")
  }

  b<- y %>%
    html_nodes("#formfield-form-widgets-icms_secundario div") %>%
    html_text()
  if(all.equal(b,character(0))==TRUE)
  {
    b=0
  } else
  {
    b<-substr(b,4,100)
    b = type.convert(b, na.strings = "NA", as.is = F, dec = ",",numerals = "no.loss")
  }
  #puting the information scraped into the data frame
  df<-data.frame(estate,year,month,a,b)
  icms<-rbind(icms,df)
  print(paste(url))
}

 > icms_data("SP","2018", "01")
Loading required package: xml2
Loading required package: bitops
[1] "https://www.confaz.fazenda.gov.br/legislacao/boletim-do-icms/SP/201801"

1 个答案:

答案 0 :(得分:1)

首先,由于您的输出包含打印的URL,因此看起来整个函数体都已执行。

从函数的名称来看,我假设您希望它返回变量icms

R是一种函数式编程语言,因此函数返回其最后执行的表达式作为结果。

因此,您应该在函数的最后放置icmsreturn(icms)

icms_data <- function(...){

     <everything else you wrote>

     icms<-rbind(icms,df)
     print(paste(url))
     icms
     }

更多背景信息:使用<-=在函数内部进行的变量分配是函数环境的 local 变量,这意味着它们将无法在功能主体之外使用。如果要将这些变量放在函数之外,则需要(a)如上所述返回它们,或(b)将它们分配给其他环境(例如,使用<<-设置“全局变量”)。通常应该避免使用选项(b),除非您详细了解正在执行的操作的含义,否则它可能导致名称冲突,而这很难调试。