<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arquivos Linguagens de programação - Estatidados</title>
	<atom:link href="http://estatidados.com.br/category/linguagens/feed/" rel="self" type="application/rss+xml" />
	<link>http://estatidados.com.br/category/linguagens/</link>
	<description>Comunidade de Estatística</description>
	<lastBuildDate>Thu, 09 Jun 2022 20:11:55 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Using RSelenium for task automation and web scraping</title>
		<link>http://estatidados.com.br/using-rselenium-for-task-automation-and-web-scraping/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-rselenium-for-task-automation-and-web-scraping</link>
					<comments>http://estatidados.com.br/using-rselenium-for-task-automation-and-web-scraping/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 12 Jul 2021 16:25:19 +0000</pubDate>
				<category><![CDATA[ciencia de dados]]></category>
		<category><![CDATA[Fabrício Barbacena]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=629</guid>

					<description><![CDATA[<p>1. Introduction This article aims to present the RSelenium package’s basic functionalities and show how it can help you to perform many useful daily tasks automatically in your internet browser. RSelenium also offers a great opportunity to observe object-oriented programming<a class="leiamais" href="http://estatidados.com.br/using-rselenium-for-task-automation-and-web-scraping/" title="Using RSelenium for task automation and web scraping">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/using-rselenium-for-task-automation-and-web-scraping/">Using RSelenium for task automation and web scraping</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1400/1*97R0jpJ07MFksAfwNXG4cw.png" alt=""/><figcaption>image by&nbsp;<a href="https://undraw.co/">unDraw</a></figcaption></figure>



<h2 class="wp-block-heading"><strong>1. Introduction</strong></h2>



<p>This article aims to present the RSelenium package’s basic functionalities and show how it can help you to perform many useful daily tasks automatically in your internet browser. RSelenium also offers a great opportunity to observe object-oriented programming (OOP) fully implemented in R.</p>



<p>In order to use RSelenium, first you need to install it&nbsp;with the&nbsp;<code>install.packages("RSelenium")</code>&nbsp;command. Be carefull to write the first two letter as capital ones. Besides, the Java software needs to be installed in your machine too, or later you will face the following error:&nbsp;<code>error in java_check () : PATH to JAVA not found</code>. A very few functions from the tidyverse will also appear in our code, so install it with&nbsp;<code>install.packages("tidyverse")</code>&nbsp;if you haven’t yet. Also, the package&nbsp;<code>getPass</code>&nbsp;might be useful if we want to send sensitive login information in our code.</p>



<p>In our examples of browser manipulation, we used the version 91.0.4472.77 of Google Chrome in a Windows environment and R version 4.0.5. However, RSelenium can be used with other combinations of internet browser and operational system. Check out the&nbsp;<a href="https://cran.r-project.org/package=RSelenium">RSelenium official documentation page</a>&nbsp;for more information about these topics.</p>



<p>The following images in this article are all mines, except the few times when the webpages&nbsp;<a href="https://quotes.toscrape.com/">https://quotes.toscrape.com/</a>&nbsp;and&nbsp;<a href="http://httpbin.org/forms/post">http://httpbin.org/forms/post</a>&nbsp;(two popular sites for webscraping exercises) or their HTML code are reproduced here. I used an R Jupyter Notebook during development but the code can be run in RStudio for sure too. You will find both a Jupyter Notebook and an R script with the complete code on&nbsp;<a href="https://github.com/fabricius1/SeleniumTutorials"><strong><em>my Github repository</em></strong></a>.</p>



<p>For people who might be interested in learning Selenium for Python, there is another notebook on the same Github repository with the code translated to this programming language.</p>



<h2 class="wp-block-heading"><strong>2. Importing packages and writing a helper function</strong></h2>



<p>Let’s start by importing the libraries to be used in our code.</p>



<div class="wp-block-group is-layout-flow wp-block-group-is-layout-flow"><div class="wp-block-group__inner-container"></div></div>



<pre class="wp-block-code"><code># Import libraries
library("RSelenium")
library("tidyverse")
library("getPass")

# This line makes R show messages in English.
# Use "pt" if you want them to be displayed in Portuguese
Sys.setenv("LANG" = "en")</code></pre>



<div class="wp-block-group is-layout-flow wp-block-group-is-layout-flow"><div class="wp-block-group__inner-container"></div></div>



<p>I also created a customized function called&nbsp;<code>check_object</code>&nbsp;that will print the&nbsp;<code>class</code>&nbsp;and&nbsp;<code>typeof</code>&nbsp;functions info, which will help us to analyze the new RSelenium objects we will find on our way.</p>



<pre class="wp-block-code"><code># Customized function to check class() and typeof() at once:
check_object &lt;- function(object) {
    cat("\nclass: ",
        class(object),
        "\ntypeof: ",
        typeof(object),
        "\n")
}</code></pre>



<h2 class="wp-block-heading"><strong>3. First RSelenium objects: rsClientServer and remoteDriver</strong></h2>



<p>The next step is to create an RSelenium rsClientServer, which we will save in the computational variable called&nbsp;<code>client_server</code>. The code below will automatically open a new Chrome window and give us more information about the object we have just created.</p>



<pre class="wp-block-code"><code># Create rsClientServer object with Google Chrome browser.
# Change the chromever argument for the Chrome version used in your machine
client_server &lt;- RSelenium::rsDriver(browser=c("chrome"), 
                                     chromever="91.0.4472.101", 
                                     port=4545L, 
                                     verbose=F)
check_object(client_server)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*lWOeoedUXsN_wEqQLf_Pgw.png" alt=""/></figure>



<p>Note that I passed a specific Chrome version as a string in the&nbsp;<code>chromever</code>&nbsp;argument. So, you will need to adjust it according to your reality. Some arguments in&nbsp;<code>RSelenium::rsDriver()</code>&nbsp;use&nbsp;<code>"latest"</code>&nbsp;as default value, which can cause errors if an installed version from Selenium or the chosen browser is different from the latest available version, even if it is a beta one. I experienced that issue with Chrome while finishing this article and I want you to be prepared if you wind up facing a similar obstacle.</p>



<p>Now it is time to save the RSelenium remoteDriver into the computational variable called&nbsp;<code>driver</code>. This object is by far the most important one in our code. As we will discover later, we will spend most of the time calling methods from the remoteDriver object to manipulate the browser and get the information we need.</p>



<pre class="wp-block-code"><code># Save the remoteDriver object in the computational variable called "driver"
driver &lt;- client_server&#91;&#91;"client"]]
check_object(driver)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*KmcTynX1BwnpB5oMvfAHTA.png" alt=""/></figure>



<h2 class="wp-block-heading"><strong>4. Navigate to a new webpage</strong></h2>



<p>We will start by telling the remote driver to open the site&nbsp;<a href="https://quotes.toscrape.com/">https://quotes.toscrape.com/</a>. One can do that by calling the&nbsp;<code>navigate()</code>&nbsp;method from the remoteDriver object and using the URL as the method argument:</p>



<pre class="wp-block-code"><code># Navigate to the page to be scraped
url &lt;- "https://quotes.toscrape.com/"
driver$navigate(url)</code></pre>



<p>After running this code, the Chrome window controlled by RSelenium will open the chosen site.</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*DVTs5nupwUSmmSD4VbVFXA.png" alt=""/></figure>



<p>Whenever you need your code to return the current webpage URL, you can call&nbsp;<code>driver$getCurrentUrl()</code>. And if you want to work with a maximized browser window, just call&nbsp;<code>driver$maxWindowSize()</code>.</p>



<pre class="wp-block-code"><code># Get the current url
driver$getCurrentUrl()

# Maximize window
driver$maxWindowSize()</code></pre>



<p>Here I would like to make a very important observation: the browser window controlled by RSelenium will close automatically if there is no new activity for a while. If that happens, you will probably have to run the code below in order to free the port you last used in your RSelenium program. I found this line of code on StackOverflow after facing this problem for the first fime and now I use it whenever I run into such an issue.</p>



<pre class="wp-block-code"><code># This line is very important: run it if your Selenium 
# remoteDriver crashes and you can't open another one in the same port

system("taskkill /im java.exe /f", intern=FALSE, ignore.stdout=FALSE)</code></pre>



<h2 class="wp-block-heading"><strong>5. The&nbsp;</strong><code><strong>driver$findElement()</strong></code><strong>&nbsp;method</strong></h2>



<p>The first element to be manipulated will be the login link, located in the webpage upper right corner. We will do that later by calling the&nbsp;<code>driver$findElement()</code>&nbsp;method with its two arguments (<code>using</code>&nbsp;and&nbsp;<code>value</code>).</p>



<p>However, since this method is so important, let’s take a quick look at all options available to the&nbsp;<code>using</code>&nbsp;parameter. Running&nbsp;<code>driver$findElement</code>, without the parentheses, will return information about this method. Please note that only the first lines from the output are reproduced below.</p>



<pre class="wp-block-code"><code>driver$findElement</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*PfMp0shtO0xSKB_n-ppD7A.png" alt=""/></figure>



<p>As we can observe from the last reproduced output, the&nbsp;<code>using</code>&nbsp;parameter accepts one of the following strings:</p>



<ul class="wp-block-list"><li><code>"xpath"</code>&nbsp;=&gt; find the element in the page by using the Xpath query language;</li><li><code>"css selector"</code>&nbsp;=&gt; use a selector from the CSS style sheet language to find the element;</li><li><code>"id"</code>&nbsp;|&nbsp;<code>"name"</code>&nbsp;|&nbsp;<code>"class name"</code>&nbsp;=&gt; these three options use respectively the id attribute, the name attribute, and the class attribute from the HTML tags to find an element in the webpage;</li><li><code>"link text"</code>&nbsp;|&nbsp;<code>"partial link text"</code>&nbsp;=&gt; when you deal with an HTML anchor tag (example:&nbsp;<code>&lt;a&gt;this is the link text&lt;/a&gt;</code>), you can find them by searching for either the partial or the complete link text.</li></ul>



<h2 class="wp-block-heading"><strong>6. Working with an RSelenium webElement</strong></h2>



<p>So, let’s use the Xpath to find the login link element. One can do that on Chrome by right-clicking on the login link and then choosing the&nbsp;<em>inspect</em>&nbsp;option. This will open the DOM panel and show its HTML code.</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*lS4jDoqwYWXcquaaWHV5Nw.png" alt=""/></figure>



<p>Now, in your browser, right-click on the HTML &lt;a&gt; login element (the line highlighted in blue in the image above) and then choose “<em>Copy”&nbsp;</em>and “<em>Copy full Xpath</em>” in the auxiliary menu. Paste the Xpath information into a string and use it inside&nbsp;<code>driver$findElement()</code>, as follow:</p>



<pre class="wp-block-code"><code># Get the login link element by using xpath
login_xpath &lt;- "/html/body/div/div&#91;1]/div&#91;2]/p/a"
login_link &lt;- driver$findElement(using = "xpath", value = login_xpath)
check_object(login_link)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*fr34JyPy92scevqy7ln-HQ.png" alt=""/></figure>



<p>As one can observe, the method&nbsp;<code>driver$findElement()</code>&nbsp;returns an RSelenium webElement object. When saved in a computational variable like&nbsp;<code>login_link</code>, this webElement can be used to call other methods too, as shown below:</p>



<pre class="wp-block-code"><code># This method returns the element tag name
login_link$getElementTagName()

# This method returns the element inner text
login_link$getElementText()

# This method returns an element attribute (in this case, "href")
login_link$getElementAttribute("href")</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*nbIJaR6moSf01c6zqcsPqA.png" alt=""/></figure>



<p>You can also click on a webElement. In the current example, this will send us to the login page.</p>



<pre class="wp-block-code"><code># Click on the element
login_link$clickElement()</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*Ikr-T4mSRZC8DuC0F6SJEg.png" alt=""/></figure>



<h2 class="wp-block-heading"><strong>7. Make your code take a little break with&nbsp;</strong><code><strong>Sys.sleep()</strong></code></h2>



<p>We will manipulate this login page later. By now, let’s run the following code so that we can go back to the main page and wait for 2.5 seconds. Then we return to the login page and wait for another 2 seconds:</p>



<pre class="wp-block-code"><code># Go back to the last page and wait 2.5 seconds
driver$goBack()
Sys.sleep(2.5)
cat("ok")</code></pre>



<pre class="wp-block-code"><code># Go forward in the browser history and wait 2 seconds
driver$goForward()
Sys.sleep(2)
cat("ok")</code></pre>



<p>When we work with RSelenium, asking the program to wait a couple of seconds before moving to a new page is an excellent strategy. Actually, this additional time before moving on is almost a mandatory strategy in order to avoid errors that can crash the code.</p>



<p>For example, if we go to a new page and ask RSelenium to find an HTML element that has not been loaded yet, we will get a NoSuchElement Error. And if that happens during a long loop and a lot of data has already been scraped, all the effort done by then might get lost. Thus, waiting a few seconds is a more preferable approach. You could also use&nbsp;<code>try()</code>&nbsp;and&nbsp;<code>tryCatch()</code>&nbsp;statements so that your code can be prepared for some of the most common errors before they occur.</p>



<h2 class="wp-block-heading"><strong>8. Write a function to go back to the first page</strong></h2>



<p>If we were to click on the&nbsp;<em>Quotes to Scrape</em>&nbsp;link, the browser goes back to the first page. The image below shows this link HTML code:</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*7tlxmkq377dCY4vSGW6oVQ.png" alt=""/></figure>



<p>Let’s find this link now with RSelenium by using the following CSS selector:</p>



<pre class="wp-block-code"><code>
# This code uses a css selector to get the link to the main page
css_selector &lt;- "div.header-box.row > div.col-md-8 > h1 > a"
main_page_link &lt;- driver$findElement("css selector", css_selector)
check_object(main_page_link)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*fr34JyPy92scevqy7ln-HQ.png" alt=""/></figure>



<p>In CSS, class attributes are represented by a dot, and id attributes are represented by a hashtag symbol. The&nbsp;<code>css_selector</code>&nbsp;string we reproduced above can be read as follow: “find the first&nbsp;<code>div</code>&nbsp;HTML tag that has both the&nbsp;<code>header-box</code>&nbsp;and&nbsp;<code>row</code>&nbsp;classes, then find a&nbsp;<code>div</code>&nbsp;with the&nbsp;<code>col-md-8</code>&nbsp;class inside it. Next, find a&nbsp;<code>h1</code>&nbsp;heading, and then return the first link element inside it”.</p>



<p>We can get some info from this new element and click on it too so that the browser goes to the first page.</p>



<pre class="wp-block-code"><code># Get the element info
main_page_link$getElementTagName()
main_page_link$getElementText()
main_page_link$getElementAttribute("style")

# Click on the link
main_page_link$clickElement()</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*d9c1XKCiKrHG0RDnfuQgBg.png" alt=""/></figure>



<p>Now we are ready to write our first customized function using RSelenium code, which will be helpful whenever we want to go back to the first page in this website. Note here the phenomenon of method-chaining (a method called right after another method), which is a very common practice when working with OOP. This new function of ours will not return a webElement object, since the last action it performs is to click on the link. So, the function will return&nbsp;<code>NULL</code>&nbsp;because that is the value returned by the&nbsp;<code>clickElement()</code>&nbsp;method.</p>



<pre class="wp-block-code"><code># This function makes the browser return to the main page
return_to_main_page &lt;- function() {
    css_selector &lt;- "div.header-box.row > div.col-md-8 > h1 > a"
    driver$findElement("css selector", css_selector)$clickElement()
}</code></pre>



<h2 class="wp-block-heading"><strong>9. Gather all links in a webpage with&nbsp;</strong><code><strong>driver$findElements()</strong></code></h2>



<p>Our next action will be to scrape all links in the first page. This can be done by the&nbsp;<code>findElements()</code>&nbsp;method (note the additional letter&nbsp;<em>s&nbsp;</em>in the end). While&nbsp;<code>findElement()</code>&nbsp;(singular) returns the first webElement object in the DOM to match the search criteria,&nbsp;<code>findElements()</code>&nbsp;(plural) returns a list with ALL webElements objects with given criteria.&nbsp;<code>findElements()</code>&nbsp;will also demand the same&nbsp;<code>using</code>&nbsp;and&nbsp;<code>value</code>&nbsp;parameters we talked about earlier. If no webElement is found with the arguments passed to&nbsp;<code>findElements()</code>, an empty list will be returned by it.</p>



<p>If we perform a search using only the&nbsp;<code>&lt;a&gt;</code>&nbsp;tag name, we will find 55 links in the first page.</p>



<pre class="wp-block-code"><code># The method findElements() returns a list of Web Elements.
# This code finds all links in page 1 by using the tag name
return_to_main_page()

all_links_page_1 &lt;- driver$findElements("tag name", "a")

cat(paste("number of links in main page: ",
          length(all_links_page_1),
          "\n\n")
   )

cat("object", quote(all_links_page_1), "\n")
check_object(all_links_page_1)

cat("\n\nseventh object in", quote(all_links_page_1), "list:\n")
check_object(all_links_page_1&#91;&#91;7]])</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*d5zy_1sN85mSvyN7DrGxeg.png" alt=""/></figure>



<p>We can choose to print to the console the inner text and URL from all the link elements in the first page. In order to do that, let’s first create another function.</p>



<pre class="wp-block-code"><code># The function below, when used in a webElement with the "a" tag name,
# returns the link inner text and its url.
# Both info are also printed on the console if print_output = TRUE
show_links_info &lt;- function(link_element, print_output = TRUE) {
    text &lt;- as.character(link_element$getElementText())
    url &lt;- as.character(link_element$getElementAttribute("href"))
    if (print_output) {
        cat(paste0(text, ": "),
            url,
            "\n")
        # line below makes the info be displayed during iteration
        flush.console()
    }
        
    c(text, url)
}</code></pre>



<p>This new function must receive an RSelenium webElement with an HTML&nbsp;<code>&lt;a&gt;</code>&nbsp;tag, since we will look for its inner text and&nbsp;<code>href</code>&nbsp;attibute. So, if the&nbsp;<code>print_output</code>&nbsp;parameter is set to&nbsp;<code>TRUE</code>, the code inside the if statement is executed and the element inner text and URL will be printed to the console gradually, since&nbsp;<code>flush.console()</code>&nbsp;is called there. A vector with&nbsp;<code>text</code>&nbsp;and&nbsp;<code>url</code>is returned by the function.</p>



<p>The code below with&nbsp;<code>lapply</code>&nbsp;will print all the information from the&nbsp;<code>all_links_page_1</code>&nbsp;list. The computational variable&nbsp;<code>saved_list</code>&nbsp;allows to access this info in a list of lists too, if necessary. Only part of the output is reproduced below:</p>



<pre class="wp-block-code"><code># Use lapply to apply the show_links_info function to the list with
# all the links in the first page
saved_list &lt;- lapply(all_links_page_1, show_links_info)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*3xQAhZBeftO1baB4Q2WeCw.png" alt=""/></figure>



<p>If we prefer to save the links information into a data frame, that can be done by a for loop, with each iteration calling&nbsp;<code>show_links_info()</code>&nbsp;and appending this info to a new computational variable called&nbsp;<code>links_dataframe</code>.</p>



<pre class="wp-block-code"><code># The code below saves all links from page 1 in a dataframe

links_dataframe &amp;lt;- data.frame()

for (i in 1:length(all_links_page_1)) {
    links_info &amp;lt;- show_links_info(all_links_page_1&#91;&#91;i]], print = FALSE)
    temp_data_frame &amp;lt;- data.frame(index = nrow(links_dataframe) + 1,
                                  text = stringr::str_trim(links_info&#91;1]),
                                  url = links_info&#91;2])
    links_dataframe &amp;lt;- rbind(links_dataframe, temp_data_frame)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*vQWCR_K0zOLFU6C6IIJzRw.png" alt=""/></figure>



<h2 class="wp-block-heading"><strong>10. Go through all pages in a website</strong></h2>



<p>Another very common task we might need to perform is to visit all pages in a website by following a next link, for example. And in each page, we can perform an action, like scraping some information.</p>



<p>Since we cannot be sure of how many pages a site has beforehand, we need code that keeps repeating an action until a condition becomes true and the code stops executing. That is right, this is a perfect scenario to use a&nbsp;<code>repeat</code>&nbsp;loop with a&nbsp;<code>break</code>&nbsp;inside an if statement. At first, this loop of ours will only go through every page and then print the page number to the console.</p>



<pre class="wp-block-code"><code>
# This code clicks on the "next" link and moves along the pages.
# When the last page is reached and there is no next link, break the loop.
return_to_main_page()
i &lt;- 1

repeat {
    cat("\npage ", i)
    flush.console()
    i &lt;- i + 1
    
    next_link_as_list &lt;- driver$findElements(using="css selector", "li.next > a")

    if (length(next_link_as_list) == 0) {
        break
    }
    
    next_link_as_list&#91;&#91;1]]$clickElement()
    Sys.sleep(2)
    
    
}

cat("\nwe reached the last page")
return_to_main_page()
cat("\nback to page 1\n")</code></pre>



<p>Note that the next link is located by using&nbsp;<code>driver$findElements()</code>&nbsp;in line 11. So, this code will return either a list with one webElement or a list with no element at all. This is a nice way of avoiding the NoSuchElement Error that would have been raised in the last page if we had used the&nbsp;<code>driver$findElement()</code>&nbsp;method instead. So, when&nbsp;<code>next_link_as_list</code>&nbsp;has a length of zero, the code will enter the conditional and break the loop, and we will have accomplished our goal of going through all pages in the website.</p>



<h2 class="wp-block-heading"><strong>11. Writing code to open a specific page in the website</strong></h2>



<p>After the last code execution, we discovered that the site has only 10 pages with quotes. Besides, all pages from 2 to 10 share the following url pattern:&nbsp;<em>https://quotes.toscrape.com/page/</em>&nbsp;plus the page number added to its end. This kind of situation is a very desirable one because it allows you to move to new pages by just sending the specific url pattern directly to the&nbsp;<code>driver$navigate()</code>&nbsp;method. So, if you know all the pages range beforehand, this approach will be much easier than finding link elements and clicking on them to change pages.</p>



<p>Let’s now create a function that will send us directly to a chosen page in our website. We will add some boolean conditions in it so that the function can check the argument class and raise an exception if it is a character one. The function will also truncate decimal numbers and raise an error if the number passed to it is not between 1 to 10.</p>



<pre class="wp-block-code"><code># From the code above, we discovered that there are 10 pages in the website.
# The function below goes to a chosen page and it will raise an error
# if the argument passed is not an integer number between 1 and 10
go_to_page &lt;- function(page_number=1) {
    if (is.character(page_number)) {
        cat("Error: you passed a string as argument.")
    }
    
    if (!is.numeric(page_number) ||
        as.integer(page_number) &lt; 1 ||
        as.integer(page_number) > 10 ) {
        stop("Provide an integer number between 1 and 10 as argument")
    }
    
    if (page_number %% 1 != 0) {
        page_number &lt;- trunc(page_number)
        cat(quote(page_number), "truncated to", page_number)
    }
    
    if (page_number != 1) {
        base_url_page &lt;- "https://quotes.toscrape.com/page/"
        driver$navigate(paste(base_url_page, as.character(page_number), sep=""))    
    } else {
        return_to_main_page()
    }
}</code></pre>



<p>Now, we can go to page 3 and page 7 directly by running this code:</p>



<pre class="wp-block-code"><code># Go to page 3, wait 2.5 seconds and then go to page 7
go_to_page(3)
driver$getCurrentUrl()

Sys.sleep(2.5)

go_to_page(7)
driver$getCurrentUrl()</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/456/1*fZHDn2nyTn5vNABjdzIIbg.png" alt=""/></figure>



<p>If we ask to go to page&nbsp;<code>pi</code>&nbsp;by mistake instead of page 3, the function will let us know that it used a truncated version of&nbsp;<code>pi</code>, leading us then to page 3.</p>



<pre class="wp-block-code"><code># This code truncates 3.14 to 3 and then go to page 3
go_to_page(pi)
Sys.sleep(2.5)
driver$getCurrentUrl()</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/417/1*8KZ2Ovw9--Uw1DrsF-tMEQ.png" alt=""/></figure>



<p>And any of the following function calls will return an error:</p>



<pre class="wp-block-code"><code># The following function calls will return errors

go_to_page("page number 3")
go_to_page("3")
go_to_page("3.1415")
go_to_page(25)
go_to_page(97.75)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*waCa3GUQRkT3fmRoo1Cqcg.png" alt=""/></figure>



<p>And what if we wanted to retrieve an information from the current URL and save it in a computational variable, like the current page number, for example? The following code will transform the current URL in a string, split it by the&nbsp;<code>/</code>&nbsp;characters and save this info in a list of strings. Then it will get the last element of this list, which will be the page number for any page but the first one.</p>



<pre class="wp-block-code"><code># The code below will extract the page number from the current url
go_to_page(10)

my_url &lt;- as.character(driver$getCurrentUrl())
cat(my_url, "\n")

split &lt;- base::strsplit(my_url, "/")
cat(unlist(split)&#91;length(unlist(split))])

return_to_main_page()</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*CEtdXWSd71rpd4cQBcxCew.png" alt=""/></figure>



<h2 class="wp-block-heading"><strong>12. Saving the quotes info as strings</strong></h2>



<p>Now, it is time for us to tackle the main information in the website: the quotes. Before we can save them all in a nice data frame (R programmers do like saving info in data frames, don’t they?), I will show you a way of accessing all the quotes text information at once. Below we reproduce the HTML structure from one of these quotes (the vertical blue line marks all children tags inside a quote box):</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*IBAPrQ6nCA-05CQZeJDLOw.png" alt=""/></figure>



<p>When we use the&nbsp;<code>getElementText()</code>&nbsp;method from a webElement object, we not only access its own inner text but also the inner texts from all its children tags. So, if each quote info is inside a&nbsp;<code>div</code>&nbsp;tag with a&nbsp;<code>quote</code>&nbsp;class, represented in CSS selector by&nbsp;<code>div.quote</code>, we can print all quotes information from page 1 by running the following code (output is only parcially reproduced below):</p>



<pre class="wp-block-code"><code># This code reproduces all the first ten quotes as a long string.
# It shows how you can use the getElementText() method to access the
# inner text from all children elements at once.
string &lt;- ""
quotes_divs_list &lt;- driver$findElements("css selector", "div.quote")
string &lt;- unlist(lapply(quotes_divs_list, function(element) {
    string &lt;- paste(string, 
                    as.character(element$getElementText()),
                    "\n\n",
                    sep="")
    return(string)
}))

cat(string)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*DrIl13preDQ1lP4s5BCIVg.png" alt=""/></figure>



<h2 class="wp-block-heading"><strong>13. Saving the quotes info as a data frame</strong></h2>



<p>In our effort to save the quotes information into a data frame, let’s first create the following auxiliary functions:</p>



<pre class="wp-block-code"><code># Customized functions to be used in the next sapply() and lapply() calls in this code:
get_element_text &lt;- function(element) {
    as.character(element$getElementText())
}

get_link_href &lt;- function(element) {
    as.character(element$getElementAttribute("href"))
}

click_element &lt;- function(element) {
    element$clickElement()
}</code></pre>



<p>If we run the code below, we can get all quotes info in the first page and save them to computational variables:</p>



<pre class="wp-block-code"><code># With this code one can get all the info for the quotes in the current page
return_to_main_page()
quotes_text &lt;- sapply(driver$findElements("css selector", "span.text"),
                      get_element_text)
authors_text &lt;- sapply(driver$findElements("css selector", "small.author"),
                       get_element_text)
authors_links &lt;- sapply(driver$findElements("partial link text", "(about)"),
                        get_link_href)
tags_text &lt;- sapply(driver$findElements("css selector", "div.tags"),
                    get_element_text)</code></pre>



<p>These three functions we created will be used to get the quotes information from each page (like we did for page 1) and save it in vectors that will eventually be appended to the&nbsp;<code>all_quotes</code>&nbsp;data frame. Notice that we will also loop over the pages using the&nbsp;<code>repeat</code>&nbsp;structure we built before, even though we use a&nbsp;<code>while (TRUE)</code>&nbsp;loop here instead.</p>



<pre class="wp-block-code"><code>
# Now, we only need to loop over all pages and save the quotes info into a dataframe
return_to_main_page()
all_quotes &lt;- data.frame()
i &lt;- 0

while (TRUE) {
    quotes_texts &lt;- sapply(driver$findElements("css selector", "span.text"),
                           get_element_text)
    authors_texts &lt;- sapply(driver$findElements("css selector", "small.author"),
                            get_element_text)
    authors_links &lt;- sapply(driver$findElements("partial link text", "(about)"),
                            get_link_href)
    tags_texts &lt;- sapply(driver$findElements("css selector", "div.tags"),
                         get_element_text)
    page_quotes &lt;- data.frame("sequence" = (i * 10 + 1):(i * 10 +10),
                              "quote" = quotes_texts,
                              "author" = authors_texts,
                              "author_biography_link" = authors_links,
                              "tags" = tags_texts)
    
    all_quotes &lt;- rbind(all_quotes, page_quotes)
    i &lt;- i + 1
    cat("\npage", i)
    flush.console()
    
    try(next_link_as_list &lt;- driver$findElements(using="css selector", "li.next > a"),
        silent = TRUE)
    
    if (length(next_link_as_list) == 0) {
        break
    }
    
    next_link_as_list&#91;&#91;1]]$clickElement()
    Sys.sleep(2)
    
}</code></pre>



<p>If we want, we can save the&nbsp;<code>all_quotes</code>&nbsp;data frame as a CSV file, check the data frame dimensions and look at its first rows.</p>



<pre class="wp-block-code"><code># save the all_quots dataframe as a CSV file
write.csv(all_quotes,
          file = "quotes.csv",
          quote = FALSE,
          row.names = FALSE,
          fileEncoding = "UTF-8")

cat(paste0("all_quote data frame dimensions: ", nrow(all_quotes), ", ", ncol(all_quotes)))

head(all_quotes, 3)</code></pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/2000/1*BDWc0uEIGJxD4jnqk_igfg.png" alt=""/></figure>



<p>Pretty amazing, right?</p>



<h2 class="wp-block-heading"><strong>14. Saving the authors’ biographical info as a data frame</strong></h2>



<p>However, there are still some interesting information in this website waiting to be scraped by us. If you navigate to the first link in the statistical variable&nbsp;<code>all_quotes$author_biography_link</code>, you will find biographical information about Albert Einstein. Every author quoted in the website has a page like that. The good news is that we already gathered all these biographical links, we only need to loop over them and save the scraped information into another data frame called&nbsp;<code>authors_info</code>. The following code accomplishes that task.</p>



<pre class="wp-block-code"><code># Each author has a biography page. We can get that info too.
# This will get all the unique authors biography links
unique_links_biographies &lt;- unique(all_quotes$author_biography_link)
cat("total of biographical pages:", length(unique_links_biographies))

# Now we can loop over these biography links and save their info in a dataframe
authors_info &lt;- data.frame()

for (link in unique_links_biographies) {
    driver$navigate(link)
    Sys.sleep(3)
    index &lt;- nrow(authors_info) + 1
    name &lt;- driver$findElement("css selector", "h3.author-title")$getElementText()
    born_date &lt;- driver$findElement("css selector", "span.author-born-date")$getElementText()
    born_location &lt;- driver$findElement("css selector", "span.author-born-location")$getElementText()
    description &lt;- driver$findElement("css selector", "div.author-description")$getElementText()
    
    cat("\n", index, "of", length(unique_links_biographies))
    flush.console()
    
    new_row &lt;- data.frame("index" = index,
                          "name" = as.character(name),
                          "born_date" = as.character(born_date),
                          "born_location" = as.character(born_location),
                          "description" = as.character(description))
    
    authors_info &lt;- rbind(authors_info, new_row) 
}

head(authors_info)</code></pre>



<p>After we loop over all the 50 biographical pages, we will have a new nice data frame with all this information and we can saved it in a new CSV file, for example. Notice that this program logic can be reused and applied to many web scraping tasks. Find the data you need, make sure to follow the website robots.txt instructions and be happy!</p>



<h2 class="wp-block-heading"><strong>15. Manipulate text input boxes in the login page</strong></h2>



<p>Now it is time for us to start manipulating form elements, which is a very important skill to add to our task automation kit. Let’s go back to the login page and save the two text input boxes into computational variables.</p>



<pre class="wp-block-code"><code># Now we go to the login page and play a little with the text input boxes.

# Go to the login page
login_xpath &lt;- "/html/body/div/div&#91;1]/div&#91;2]/p/a"
driver$findElement(using = "xpath", value = login_xpath)$clickElement()

# Save the text input boxes elements in variables, using their id (two forms):
username_input &lt;- driver$findElement("id", "username") 
password_input &lt;- driver$findElement("css selector", "#password")</code></pre>



<p>When handling text input HTML elements, two methods are definitely very useful:&nbsp;<code>clearElement()</code>&nbsp;and&nbsp;<code>sendKeysToElement()</code>. It is a good idea to start by calling the former so that any previous content might get cleared before you start sending new information to the text box. As for the second method, it receives a list with a string as its sole element.</p>



<pre class="wp-block-code"><code>
# Username and password values
# (one can also use base::readline() or getPass::getPass() 
# to ask for user input)
username &lt;- "Fabrício"
password &lt;- "1234 is not a secure password!"

# When dealing with input boxes, it is good practice to clear their value first
username_input$clearElement()

# Send the username information (it needs to be passed as a list)
username_input$sendKeysToElement(list(username))

# Do the same with password
password_input$clearElement()
password_input$sendKeysToElement(list(password))

# Once you don't need the username and password variables anymore, delete them
rm(username, password)</code></pre>



<p>In order to submit the form and login in the site, we still need to press the login button. We can do that by using the&nbsp;<code>submitElement()</code>, available for some HTML elements that have the ability of submiting information to the website.</p>



<pre class="wp-block-code"><code># Find the submit button
submit_button &lt;- driver$findElement("css selector", "input.btn.btn-primary")

# Use the submitElement() method to submit the form information
submit_button$submitElement()</code></pre>



<p>After we do that, nothing extraordinary will happen: we will be redirected to the first page and the login text will be changed to&nbsp;<em>Logout</em>. But we did perform some fancy activity: we wrote code to login automatically in a website. If we desire, we could do the same operation in many other sites.</p>



<p>Just be careful about letting important information, like passwords, hard-coded in your program. Don’t make the life of bad people who can steal your personal info too easy, ok? A very good option to avoid such problems is to use the&nbsp;<code>getPass</code>&nbsp;package to send sensitive input data.</p>



<h2 class="wp-block-heading"><strong>16. Working with other types of HTML input tags</strong></h2>



<p>Even though they are found on the internet very often, textboxes are not the only HTML input we can manipulate with RSelenium code in our browser. We will move now to a new website (<a href="http://httpbin.org/forms/post">http://httpbin.org/forms/post</a>) and automate the boring task of ordering pizza online. Because eating pizza is a lot of fun but ordering it… well, not that much. We can let our R program to do the ordering for us so that we can focus only on the eating, fun part.</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/700/1*Wwa08bQyHz8kCykNRiTJIQ.png" alt=""/></figure>



<p>As we can observe, besides three text boxes, this form uses radio buttons for the pizza size, checkboxes for the toppings, and a time input for the delivery time. These four elements are all input HTML tags, but they differ in their type attribute value. And depending on the chosen input type, they can have very specific HTML attributes that are not present in the others ones. We also have a textarea tag used in the delivery instructions, and a submit button to the form.</p>



<p>So, I want a large pizza with bacon, extra cheese and mushrooms to be delivered around 19:45 at my home. I just need to let my code to do the ordering for me.</p>



<p>Below you will find my answer to this challenge. However, before you check it out, see if you can imagine how this code would look like. And to make it more interesting, use a one liner to order the three toppings at once with the help of the&nbsp;<code>base::lapply()</code>&nbsp;and the&nbsp;<code>click_element()</code>&nbsp;functions (this last one was created by us earlier).</p>



<p>Another quick tip: radioboxes and checkboxes can be manipulated using the&nbsp;<code>$clickElement()</code>&nbsp;method.</p>



<p>My code to perform this task goes below:</p>



<pre class="wp-block-code"><code>
# This code choose the large option in the radio buttons
radio_buttons &lt;- driver$findElements("css selector", 'input&#91;type="radio"]')
radio_buttons&#91;&#91;3]]$clickElement()

# Choose the first, second and fourth toppings to your pizza
checkboxes &lt;- driver$findElements("css selector", 'input&#91;name="topping"]')
lapply(checkboxes&#91;-3], click_element)

# Set delivery time to 19h45
time &lt;- driver$findElement("css selector", 'input&#91;type="time"]')
time$sendKeysToElement(list("19:45"))

poetry &lt;- "
Two households, both alike in dignity\n
(In fair Verona, where we lay our scene),\n
From ancient grudge break to new mutiny,\n
Where civil blood makes civil hands unclean.\n
From forth the fatal loins of these two foes\n
A pair of star-crossed lovers take their life;\n
Whose misadventured piteous overthrows\n
Doth with their death bury their parents’ strife.\n
The fearful passage of their death-marked love\n
And the continuance of their parents’ rage,\n
Which, but their children’s end, naught could remove,\n
Is now the two hours’ traffic of our stage;\n
The which, if you with patient ears attend,\n
What here shall miss, our toil shall strive to mend.\n"

# Send aditional information to the textarea input
textarea &lt;- driver$findElement("tag name", "textarea")
textarea$sendKeysToElement(list(poetry))

# Submit form and go back
driver$findElement("css selector", "p > button")$submitElement()
Sys.sleep(5)
driver$goBack()

# Refresh the form page:
driver$refresh()</code></pre>



<h2 class="wp-block-heading"><strong>17. Finishing your work with RSelenium</strong></h2>



<p>Finally, we can ask RSelenium to close the browser window and shut down the server. We should also release the port we were using.</p>



<pre class="wp-block-code"><code># When you are done working with selenium, 
# Quit the browser and end the session
driver$quit()
driver$closeServer()
rm(driver, client_server)

# This releases the port.
system("taskkill /im java.exe /f", intern=FALSE, ignore.stdout=FALSE)</code></pre>



<h2 class="wp-block-heading"><strong>18. Last words</strong></h2>



<p>Now, we could create code to order 20 diferent pizzas, for example, if we desired to make a good surprise for our great work colleages. Then, whenever you want to ask another 20 pizzas (or 15, or 1000!), you just need to hit the run button, and RSelenium makes all the work for you.</p>



<p>That’s the beauty of task automation, and with this tutorial, we only scratched the surface of what RSelenium can do for us. However, the information published here is more than enough to allow you to continue your learning path in this area and create fantastic scripts that will save you and your team a lot of time.</p>



<p>And this saved time can be applied later in other important activities, like spending quality time with family or friends, reading, learning new skills, birdwatching, or simply relaxing. You definitely earned it after writing your automation script!</p>



<p><em>Good luck and happy automation!</em></p>



<p>P.S.: You will find more info about my work on LinkedIn, Medium, and Github:</p>



<p><a href="https://www.linkedin.com/in/fabriciobrasil">https://www.linkedin.com/in/fabriciobrasil</a></p>



<p><a href="https://fabriciusbr.medium.com/">https://fabriciusbr.medium.com/</a></p>



<p><a href="https://github.com/fabricius1">https://github.com/fabricius1</a></p>



<p>Link do post original: <a href="https://fabriciusbr.medium.com/using-rselenium-for-task-automation-and-web-scraping-250c4f2f5979">https://fabriciusbr.medium.com/using-rselenium-for-task-automation-and-web-scraping-250c4f2f5979</a></p>



<p>#coletadadedadosdaweb #linguagemR #automacao</p>
<p>O post <a href="http://estatidados.com.br/using-rselenium-for-task-automation-and-web-scraping/">Using RSelenium for task automation and web scraping</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/using-rselenium-for-task-automation-and-web-scraping/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Desenvolvimento de um aplicativo Web utilizando Python e Streamlit</title>
		<link>http://estatidados.com.br/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit</link>
					<comments>http://estatidados.com.br/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 08 Jun 2021 14:59:47 +0000</pubDate>
				<category><![CDATA[ciencia de dados]]></category>
		<category><![CDATA[Débora Gobbo]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=609</guid>

					<description><![CDATA[<p>Você quer saber como podemos criar um algoritmo de aprendizado de máquina e colocar ele disponível na sua empresa ou fora dela de uma maneira muito fácil e rápida, sem precisar configurar a AWS, Google Cloud ou Azure? Para isso<a class="leiamais" href="http://estatidados.com.br/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit/" title="Desenvolvimento de um aplicativo Web utilizando Python e Streamlit">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit/">Desenvolvimento de um aplicativo Web utilizando Python e Streamlit</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Você quer saber como podemos criar um algoritmo de aprendizado de máquina e colocar ele disponível na sua empresa ou fora dela de uma maneira muito fácil e rápida, sem precisar configurar a AWS, Google Cloud ou Azure? Para isso vamos utilizar o&nbsp;<em>Streamlit</em>. Para saber o passo a passo para isso, basta continuar a leitura.</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1112/1*PTozaqwh8vAVmgU5cJHNIA.png" alt=""/></figure>



<p>Hoje vamos executar um programa de&nbsp;<em>machine learning&nbsp;</em>(aprendizado de máquina)para verificar se a pessoa está propensa ter diabetes ou não, com base nas informações que ela vai inserir.</p>



<p>A nossa base de dados utilizada, é da Kaggle e se encontra disponível no seguinte link:&nbsp;<a href="https://www.kaggle.com/uciml/pima-indians-diabetes-database">https://www.kaggle.com/uciml/pima-indians-diabetes-database</a></p>



<p>Recomendo que antes de utilizá-la, você faça o tratamento dos dados, ok?</p>



<p>Vamos precisar também utilizar o&nbsp;<em>Streamlit</em>, mas o que ele é?</p>



<p>O&nbsp;<em>Streamlit&nbsp;</em>é um framework desenvolvido em Python que torna possível a criação de aplicativos elegantes para modelos de&nbsp;<em>machine learning</em>&nbsp;(aprendizagem de máquina) ou mesmo visualização de dados para uma simples análise exploratória de um&nbsp;<em>dataset</em>&nbsp;(conjunto de dados), além de possuir de forma nativa HTML e JavaScript, desta forma não é necessário saber programar nessas linguagens.</p>



<p>vai precisar estar realizando o download do&nbsp;<em>Streamlit</em>, através do link:&nbsp;<a href="https://streamlit.io/">https://streamlit.io/</a></p>



<p>Vamos utilizar também o PyCharm (IDE Python para desenvolvedores), link:&nbsp;<a href="https://www.jetbrains.com/pt-br/pycharm/download/#section=windows">https://www.jetbrains.com/pt-br/pycharm/download/#section=windows</a>.</p>



<p>Vale lembrar que o seu ambiente Python deve estar já configurado para que possamos dar os primeiros passos na construção do nosso App.</p>



<p>Para começarmos precisamos instalar as bibliotecas que vamos utilizar. Para isso com o PyCharm aberto no seu terminal, basta inserir os seguintes comandos:</p>



<p>1) pip install streamlit</p>



<p>2) pip install scikit-learn</p>



<p>3) pip install matplotlib</p>



<p>4) pip install pandas</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/574/1*w65u52V1w8hQRqGIQ6rMvQ.png" alt=""/></figure>



<p>Se você não lembra o que essas bibliotecas significam, temos um artigo dedicado para a explicação delas, vale a pena conferir.</p>



<p>Agora que instalamos as bibliotecas que vamos utilizar, vamos fazer a importação delas.</p>



<p>Para isto para inserir o seguinte código:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#importando as bibliotecas<br>import pandas as pd<br>import streamlit as st<br>from sklearn.metrics import accuracy_score<br>from sklearn.model_selection import train_test_split</p></blockquote>



<p>Explicando: Aqui estamos utilizando a biblioteca Pandas para trabalharmos com o conjunto de dados, a biblioteca&nbsp;<em>Streamlit</em>&nbsp;para a interface do nosso App,&nbsp;<em>Sklearn</em>&nbsp;para dividir o nosso conjunto de dados em treino e teste, utilizando para isso um classificador baseado em árvore de decisão, podendo no final verificar a acurácia do nosso modelo criado.</p>



<p>Vamos agora atribuir um título ao nosso aplicativo</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#título<br>st.write(&#8220;Prevendo Diabetes&#8221;)</p></blockquote>



<p>Realizando a leitura da base de dados:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#dataset<br><br>df = pd.read_csv(&#8220;C:/Users/Usuario/Desktop/dash/diabetes.csv&#8221;)</p></blockquote>



<p>Criando um cabeçalho:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#cabeçalho<br><br>st.subheader(&#8220;Informações dos dados&#8221;)</p></blockquote>



<p>Permitindo a inserção do nome do usuário pelo próprio.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#nomedousuário<br><br>user_input = st.sidebar.text_input(&#8220;Digite seu nome&#8221;)</p></blockquote>



<p>Escrevendo o nome do usuário que foi dado na entrada:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#escrevendo o nome do usuário<br><br>st.write(&#8220;Paciente:&#8221;, user_input)</p></blockquote>



<p>A partir daqui, vamos criar o nosso modelo, como dito anteriormente.</p>



<p>Vamos começar dividindo os nossos dados de entrada. Aqui o “x” recebe o “df.drop”, porque não queremos a coluna do campo “Outcome”, que é o campo com o resultado que diz se está ou não com diabetes, que é o que vamos estar treinando. Criamos depois a variável que precisamos para que apareça o resultado.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#dados de entrada<br><br>x = df.drop([&#8216;Outcome&#8217;],1)<br><br>y = df[&#8216;Outcome&#8217;]</p></blockquote>



<p>Agora, vamos separar o conjunto de dados em treino e teste, utilizando 20% da base para teste e o restante para treinamento.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#separa dados em treinamento e teste<br><br>x_train, x_text, y_train, y_test = train_test_split(x, y, test_size=0.2)</p></blockquote>



<p>Nesta etapa, vamos criar uma função para coletar os dados que irão ser inseridos pelos usuários. Como parâmetro, vamos definir um valor mínimo, um valor máximo e um valor&nbsp;<em>default</em>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#dados dos usuários com a função<br><br>def get_user_date():<br><br>pregnancies = st.sidebar.slider(&#8220;Gravidez&#8221;,0, 15, 1)<br><br>glicose = st.sidebar.slider(&#8220;Glicose&#8221;, 0, 200, 110)<br><br>blood_pressure = st.sidebar.slider(&#8220;Pressão Sanguínea&#8221;, 0, 122, 72)<br><br>skin_thickness = st.sidebar.slider(&#8220;Espessura da pele&#8221;, 0, 99, 20)<br><br>insulin = st.sidebar.slider(&#8220;Insulina&#8221;, 0, 900, 30)<br><br>bni= st.sidebar.slider(&#8220;Índice de massa corporal&#8221;, 0.0, 70.0, 15.0)<br><br>dpf = st.sidebar.slider(&#8220;Histórico familiar de diabetes&#8221;, 0.0, 3.0, 0.0)<br><br>age = st.sidebar.slider (&#8220;Idade&#8221;, 15, 100, 21)</p></blockquote>



<p>Criação de um dicionário para recebimento dessas informações.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#dicionário para receber informações<br><br>user_data = {&#8216;Gravidez&#8217;: pregnancies,<br><br>&#8216;Glicose&#8217;: glicose,<br><br>&#8216;Pressão Sanguínea&#8217;: blood_pressure,<br><br>&#8216;Espessura da pele&#8217;: skin_thickness,<br><br>&#8216;Insulina&#8217;: insulin,<br><br>&#8216;Índice de massa corporal&#8217;: bni,<br><br>&#8216;Histórico familiar de diabetes&#8217;: dpf,<br><br>&#8216;Idade&#8217;: age<br><br>}</p><p>features = pd.DataFrame(user_data, index=[0])<br><br><br>return features</p></blockquote>



<p>Agora estamos finalizando nosso aplicativo!!!</p>



<p>Vamos chamar a função criada e gerar um gráfico para exibir as informações.</p>



<p>O critério utilizado aqui foi a “entropia”, pois é usada para estimar a aleatoriedade da variável a prever (classe).</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>user_input_variables = get_user_date()<br><br>#grafico<br><br>graf = st.bar_chart(user_input_variables)<br><br>dtc = DecisionTreeClassifier(criterion=&#8217;entropy&#8217;, max_depth=3)<br><br>dtc.fit(x_train, y_train)</p></blockquote>



<p>Aqui verificamos a acurácia do nosso modelo:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#acurácia do modelo<br><br>st.subheader(&#8216;Acurácia do modelo&#8217;)<br><br>st.write(accuracy_score(y_test, dtc.predict(x_text))*100)</p></blockquote>



<p>Vamos agora com o resultado da previsão, para verificar se o usuário tem ou não diabetes.</p>



<p>Se o resultado for igual a “0” ele não possui diabetes, caso seja igual a “1” ele possui diabetes.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>#previsão do resultado</p><p>prediction = dtc.predict(user_input_variables)<br><br>st.subheader(&#8216;Previsão:&#8217;)<br><br>st.write(prediction)</p></blockquote>



<p>Agora vamos ver o resultado final?</p>



<p>Basta no seu terminal do PyCharm, inserir o comando para o<em>&nbsp;Streamlit</em>&nbsp;executar o seu script criado em Python, da seguinte forma: streamlit run “nome do seu script”</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/567/1*aUCuxQwnoWEdZbM2z70SuQ.png" alt=""/></figure>



<p>A seguir vamos visualizar o resultado:</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1350/1*VqQUEgFb4mGS_0G4zsP5cA.gif" alt=""/></figure>



<p>Pronto, você possui o seu primeiro aplicativo!!!</p>



<p>Deixe o seu comentário, e me siga no LinkedIn para acompanhar mais informações.</p>



<p>Obrigada pela leitura, até a próxima!</p>



<p>Link do post original: <a href="https://medium.com/data-hackers/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit-b929888456a5">https://medium.com/data-hackers/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit-b929888456a5</a></p>



<p>LinkedIn da autora: <a href="https://www.linkedin.com/in/debora-gobbo-a63a3392/">https://www.linkedin.com/in/debora-gobbo-a63a3392/</a></p>
<p>O post <a href="http://estatidados.com.br/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit/">Desenvolvimento de um aplicativo Web utilizando Python e Streamlit</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/desenvolvimento-de-um-aplicativo-web-utilizando-python-e-streamlit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Refresh de um script R com Crontab</title>
		<link>http://estatidados.com.br/refresh-de-um-script-r-com-crontab/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=refresh-de-um-script-r-com-crontab</link>
					<comments>http://estatidados.com.br/refresh-de-um-script-r-com-crontab/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 23 Feb 2021 13:25:56 +0000</pubDate>
				<category><![CDATA[Jodavid Ferreira]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Professores colaboradores]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=580</guid>

					<description><![CDATA[<p>Este post será breve e com um objetivo específico. Vamos criar um refessh em um script&#160;R&#160;com o&#160;Crontab, entretanto, esse&#160;refresh&#160;como mencionado nesse post, nada mais é do que um agendamento de tarefas, no qual o&#160;Crontab&#160;irá executar a tarefa agendada, toda vez<a class="leiamais" href="http://estatidados.com.br/refresh-de-um-script-r-com-crontab/" title="Refresh de um script R com Crontab">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/refresh-de-um-script-r-com-crontab/">Refresh de um script R com Crontab</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Este post será breve e com um objetivo específico. Vamos criar um refessh em um script&nbsp;<code>R</code>&nbsp;com o&nbsp;<code>Crontab</code>, entretanto, esse&nbsp;<code>refresh</code>&nbsp;como mencionado nesse post, nada mais é do que um agendamento de tarefas, no qual o&nbsp;<code>Crontab</code>&nbsp;irá executar a tarefa agendada, toda vez que a condição especificada ocorer.</p>



<h2 class="wp-block-heading">O que é Crontab?</h2>



<p>&#8220;O Cron é utilizado para agendar tarefas recorrentes, as tarefas são chamadas de cronjobs e são gerenciadas pelo crontab (tabela do cron).</p>



<p>Esta ferramenta vem instalada em diversas distribuições Linux, mas caso o Cron não esteja instalado na sua máquina é possível instalar através do comando abaixo (No Ubuntu)&#8221;:</p>



<pre class="wp-block-code"><code># apt-get install cron</code></pre>



<p>Para criar uma nova tarefa usamos o comando&nbsp;<strong>crontab -e</strong>&nbsp;que irá abrir o arquivo do cron para inserir o agendamento para o usuário atual.</p>



<pre class="wp-block-code"><code># crontab -e</code></pre>



<ul class="wp-block-list"><li>Se necessário usar o&nbsp;<strong>sudo</strong>&nbsp;nos comandos acima.</li></ul>



<p>O crontab possui seis colunas, que correspondem aos minutos, horas, dias, meses, semanas e, por fim, aos comandos que serão executados.</p>



<p>Abaixo segue detalhes sobre eles:</p>



<ul class="wp-block-list"><li><em>Minuto:</em>&nbsp;Valores de 0 a 59 ou *</li><li><em>Hora:</em>&nbsp;Valores de 0 a 23 ou *</li><li><em>Dia:</em>&nbsp;Valores de 1 a 31 ou *</li><li><em>Mês:</em>&nbsp;Valores de 1 a 12, jan a dec ou *</li><li><em>Semana:</em>&nbsp;0 a 6, sun a sat ou * (0 e 7 representa Domingo)</li><li><em>Comando:</em>&nbsp;O comando a ser executado ou script</li></ul>



<p>O caractere asterisco (*) significa do primeiro ao último.</p>



<p>Com o arquivo do&nbsp;<code>Crontab</code>&nbsp;aberto vamos adicionar a seginte linha&nbsp;<code>*/15 * * * * Rscript script.R</code>, após o Rscript coloca todo o caminho até o arquivo a ser executado, e nos minutos foram colocados ’*/15’ para o arquivo ser executado a cada 15 minutos.</p>



<pre class="wp-block-code"><code># 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command

*/15 * * * * Rscript 'script.R'
</code></pre>



<h2 class="wp-block-heading">Script R</h2>



<p>Vamos utilizar um script R que envia uma mensagem para o Telegram toda vez que for executado. Para isso, vou utilizar um Bot que criei no post anterior:&nbsp;<a href="https://jodavid.github.io/post/construindo-um-chatbot-para-telegram-com-r/">https://jodavid.github.io/post/construindo-um-chatbot-para-telegram-com-r/</a></p>



<p><strong>script.R:</strong></p>



<pre class="wp-block-code"><code># Pacote Necessário: telegram.bot

# Token do Bot:
bot &lt;- telegram.bot::Bot(token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")

# Adicionando id do Recepetor (abaixo como descobrir seu id no Telegram)
chatid &lt;- "574895214" #id aleatório aqui

# Enviando o horário atual
bot$sendMessage(chat_id = chatid,
                text = format(Sys.time(), "%X")
                )</code></pre>



<h2 class="wp-block-heading">Como descobrir seu id</h2>



<ol class="wp-block-list"><li>Acesse esse link pelo Telegram:&nbsp;<a href="https://t.me/my_id_bot">https://t.me/my_id_bot</a>;</li><li>Utiliza o&nbsp;<code>/start</code>;</li><li>Seu&nbsp;<code>id</code>&nbsp;do Telegram vai aparecer na tela de conversa.</li></ol>



<hr class="wp-block-separator"/>



<p>Com esse código acima, estando correto o token do bot e o id do receptor, a mensagem chegará no Telegram corretamente.</p>



<p><strong>OBS.:</strong>&nbsp;É necessário interagir com o bot após a criação dele, para que as mensagens cheguem corretamente. Não fazendo isso, o bot não consegue enviar mensagens ao usuário.</p>



<p>Fontes:</p>



<p><a href="https://medium.com/totvsdevelopers/entendendo-o-crontab-607bc9f00ed3">https://medium.com/totvsdevelopers/entendendo-o-crontab-607bc9f00ed3</a></p>



<h4 class="wp-block-heading">“Post gerado com framework HUGO (<a href="http://gohugo.io/">http://gohugo.io/</a>), R Markdown (<a href="http://rmarkdown.rstudio.com/">http://rmarkdown.rstudio.com/</a>), no qual os resultados são gerados na geração da página.”</h4>



<p>Post original:</p>



<p><a href="https://jodavid.github.io/post/construindo-um-chatbot-para-telegram-com-r/">https://jodavid.github.io/post/construindo-um-chatbot-para-telegram-com-r/</a></p>



<p>LinkedIndo autor:</p>



<p><a href="https://www.linkedin.com/in/jodavidferreira/">https://www.linkedin.com/in/jodavidferreira/</a></p>
<p>O post <a href="http://estatidados.com.br/refresh-de-um-script-r-com-crontab/">Refresh de um script R com Crontab</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/refresh-de-um-script-r-com-crontab/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Construindo um ChatBot para Telegram com R</title>
		<link>http://estatidados.com.br/construindo-um-chatbot-para-telegram-com-r/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=construindo-um-chatbot-para-telegram-com-r</link>
					<comments>http://estatidados.com.br/construindo-um-chatbot-para-telegram-com-r/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 23 Feb 2021 13:10:56 +0000</pubDate>
				<category><![CDATA[Estatística]]></category>
		<category><![CDATA[Jodavid Ferreira]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Professores colaboradores]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=574</guid>

					<description><![CDATA[<p>O Chatbot é um programa de computador que simula uma conversa humana em um chat. Dessa forma, é possível automatizar tarefas repetitivas e burocráticas, como dúvidas frequentes, na forma de diálogo pré-definido entre o usuário e um ‘robô’. Essa tecnologia<a class="leiamais" href="http://estatidados.com.br/construindo-um-chatbot-para-telegram-com-r/" title="Construindo um ChatBot para Telegram com R">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/construindo-um-chatbot-para-telegram-com-r/">Construindo um ChatBot para Telegram com R</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>O Chatbot é um programa de computador que simula uma conversa humana em um chat. Dessa forma, é possível automatizar tarefas repetitivas e burocráticas, como dúvidas frequentes, na forma de diálogo pré-definido entre o usuário e um ‘robô’. Essa tecnologia automatiza conversas e já é usada por diversas empresas e organizações para atender clientes, dar informações sobre serviços, vender produtos, entregar conteúdo, entre outras funções.</p>



<p>Essas ferramentas usam inteligência artificial e estão cada vez mais aperfeiçoadas. Ou seja, você não sabe, mas provavelmente já conversou com um robô.</p>



<p>Neste post vamos criar um ChatBot para o Telegram e controlado com software R.</p>



<h3 class="wp-block-heading">Criando o Bot no Telegram</h3>



<p>Primeiro passo é criar o Bot no Telegram, para esse passo crie uma conta no&nbsp;<a href="https://web.telegram.org/">Telegram</a>&nbsp;e em seguida procure o usuário&nbsp;<a href="https://telegram.me/botfather">@BotFather</a>&nbsp;e inicie uma conversa da seguinte forma com o seguinte comando para criar um novo bot:</p>



<pre class="wp-block-code"><code>/newbot</code></pre>



<p>Você deve obter uma resposta instantânea:</p>



<pre class="wp-block-code"><code>Alright, a new bot. How are we going to call it? Please choose a name for your bot.</code></pre>



<p>que pede para você escolher um nome para o seu Bot. Você deve enviar então o nome que deseja para o bot, que pode ser qualquer um, por exemplo:</p>



<pre class="wp-block-code"><code>JFRBot</code></pre>



<p>Em seguida receberá a seguinte mensagem:</p>



<pre class="wp-block-code"><code>Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.</code></pre>



<p>O BotFather agora pedirá que você escolha um&nbsp;<strong>nome de usuário</strong>&nbsp;para o seu Bot. Este nome de usuário deve terminar em&nbsp;<em>bot</em>&nbsp;e ser globalmente único. Neste tutorial, vou alterar um pouco o nome, mas levando em consideração que seja parecido como nome escolhido anteriormente. Envie seu nome de usuário escolhido para BotFather:</p>



<pre class="wp-block-code"><code>J_frbot</code></pre>



<p>Depois de fazer isso, o BotFather enviará a você uma mensagem de “Parabéns”, que incluirá um token.</p>



<pre class="wp-block-code"><code>Done! Congratulations on your new bot. You will find it at t.me/J_frbot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

Use this token to access the HTTP API:
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
Keep your token secure and store it safely, it can be used by anyone to control your bot.

For a description of the Bot API, see this page: https://core.telegram.org/bots/api</code></pre>



<p><strong>eu substituí o token pois ele é único, este acima é apenas um exemplo</strong>.</p>



<p>O token é esta parte: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11</p>



<p>Alguns comandos do&nbsp;<a href="https://telegram.me/botfather">@BotFather</a>&nbsp;podem ser encontrados&nbsp;<a href="https://core.telegram.org/bots#6-botfather">https://core.telegram.org/bots#6-botfather</a>.</p>



<p>Para o restante deste tutorial, indicaremos onde você precisa colocar seu token usando &lt;your-bot-token&gt; ou apenas TOKEN. Anote o token, pois você precisará dele no código que está prestes a escrever.</p>



<h3 class="wp-block-heading">Iniciando código no R</h3>



<p>Com a criação do Bot pelo Telegram concluído, vamos agora configurar o&nbsp;<code>R</code>&nbsp;para que consigamos consevar com o Bot e assim criar esse robô que está cada vez mais ganhando espaço.</p>



<p>O primeiro passo é instalar e chamar a biblioteca no qual usaremos:</p>



<pre class="wp-block-code"><code># Pacote Necessário
# install.packages(telegram.bot)

library(telegram.bot) #Pacote para Telegram</code></pre>



<p>Com o pacote instalado, é o momento de utilização do Token:</p>



<pre class="wp-block-code"><code>#Token do Bot:
bot &lt;- Bot(token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
updater &lt;- Updater(token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")

print(bot$getMe())</code></pre>



<pre class="wp-block-code"><code>## $id
## &#91;1] 1406230646
## 
## $is_bot
## &#91;1] TRUE
## 
## $first_name
## &#91;1] "JFRBot"
## 
## $username
## &#91;1] "J_frbot"
## 
## $can_join_groups
## &#91;1] TRUE
## 
## $can_read_all_group_messages
## &#91;1] FALSE
## 
## $supports_inline_queries
## &#91;1] FALSE</code></pre>



<p>Pelo resultado anterior é possível verificar que estamos conectados ao nosso Bot corretamente.</p>



<p>A seguir vamos criar algumas funções e verificar se obtemos respostas quando conversarmos com nosso Bot pelo Telegram.</p>



<pre class="wp-block-code"><code>#Funcao start
start &lt;- function(bot, update)
{
  bot$sendMessage(chat_id = update$message$chat_id,
                  text = sprintf("Olá %s, se estiver recebendo está mensagem, significa que eu existo e estou aqui!",
                                 update$message$from$first_name))
}
start_handler &lt;- CommandHandler("start", start)
updater &lt;- updater + start_handler

#Funcao hoje
hoje &lt;- function(bot, update)
{
  bot$sendMessage(chat_id = update$message$chat_id,
                  text = sprintf("A data de hoje é %s",
                                 format(Sys.Date(), "%d-%b-%Y")))
}
hoje_handler &lt;- CommandHandler("hoje", hoje)
updater &lt;- updater + hoje_handler

#Funcao echo
echo &lt;- function(bot, update){
  bot$sendMessage(chat_id = update$message$chat_id, text = update$message$text)
}

updater &lt;- updater + MessageHandler(echo, MessageFilters$text)

#Funcao histograma de uma normal
historama_normal &lt;- function(bot, update)
{
  png("my_plot.png")
  hist(rnorm(1000))
  dev.off()
  bot$sendPhoto(chat_id = update$message$chat_id, photo = 'my_plot.png')
}

hist_norm_handler &lt;- CommandHandler("hist_norm", historama_normal)
updater &lt;- updater + hist_norm_handler</code></pre>



<p>Para iniciar o chatBot utilize a função abaixo:</p>



<pre class="wp-block-code"><code>updater$start_polling()</code></pre>



<p>Nosso Bot atualmente possui 4 funções, que podem ser acessadas com&nbsp;<code>/start</code>,&nbsp;<code>/hoje</code>,&nbsp;<code>/hist_norm</code>&nbsp;e a quarta função é repetir tudo que é digitado.</p>



<p>Abaixo segue uma imagem das funções funcionando no Telegram:</p>



<figure class="wp-block-image is-resized"><img fetchpriority="high" decoding="async" src="https://jodavid.github.io/img/exemplo-chatbot.jpg#center" alt="" width="254" height="533"/></figure>



<h2 class="wp-block-heading">Menu de itens</h2>



<p>Será mostrado a seguir como criar um menu de itens como destacado na imagem abaixo. Este menu ajuda a definir e mostrar aos usuários os comandos prontos e existentes no Bot.</p>



<figure class="wp-block-image"><img decoding="async" src="https://jodavid.github.io/img/chatbot2.png" alt=""/></figure>



<p>Para criar o menu de itens, acesse o chat do&nbsp;<a href="https://telegram.me/botfather">@BotFather</a>&nbsp;que é quem comanda os Bot, e exeute o seguinte comando:</p>



<pre class="wp-block-code"><code>/setcommands</code></pre>



<p>Você receberá a mensagem abaixo se possuir mais de um Bot</p>



<pre class="wp-block-code"><code>Choose a bot to change the list of commands.</code></pre>



<p>ao escolher o Bot desejado será novamente emitida uma mensagem</p>



<pre class="wp-block-code"><code>OK. Send me a list of commands for your bot. Please use this format:

command1 - Description
command2 - Another description

Send /empty to keep the list empty.</code></pre>



<p>A seguir pode colocar a lista com todos os comandos e as descrições, no nosso exemplo, como possui 3 funções,&nbsp;<code>/start</code>,&nbsp;<code>/hoje</code>,&nbsp;<code>/hist_norm</code>&nbsp;foram colocadas essas funções como mostrados abaixo.</p>



<pre class="wp-block-code"><code>start - inicio do Bot
hoje - data atual
hist_norm - Histograma da distribuição Normal</code></pre>



<p>Se conseguiu chegar aqui e com o código em&nbsp;<code>R</code>&nbsp;mostrado estando em execução, o seu ChatBot deve estar funcionando e respondendo a seus comandos pelo Telegram.</p>



<p>O Bot só funciona se o arquivo estiver rodando no&nbsp;<code>R</code>, ou, uma outra forma é colocar num servidor que suporte códigos em&nbsp;<code>R</code>. Eu possuo o&nbsp;<code>shiny-server</code>&nbsp;instalado em minha máquina local, e dessa forma foi possível criar um arquivo, no qual, quando este aberto, o ChatBot fica funcionando, ou seja, quando eu estiver com o notebook ligado, esse Bot ensinado nesse post está funcionando e voê pode conversar com ele pesquisado-o no Telegram por&nbsp;<code>JFRBot</code>&nbsp;ou&nbsp;<code>@J_frbot</code>.</p>



<p>O artigo&nbsp;<em>Como Instalar o shiny server em seu Próprio Servidor</em>&nbsp;do Marcus Nunes mostra como instalar um servidor Shiny, o artigo é encontrado no link:&nbsp;<a href="https://marcusnunes.me/posts/como-instalar-o-shiny-em-seu-proprio-servidor/">https://marcusnunes.me/posts/como-instalar-o-shiny-em-seu-proprio-servidor/</a>.</p>



<p>Fontes:</p>



<p><a href="https://www.techtudo.com.br/noticias/2018/03/o-que-e-chatbot-entenda-como-funciona-o-robo-que-conversa-com-voce.ghtml">https://www.techtudo.com.br/noticias/2018/03/o-que-e-chatbot-entenda-como-funciona-o-robo-que-conversa-com-voce.ghtml</a></p>



<p><a href="https://cran.r-project.org/web/packages/telegram.bot/vignettes/telegrambot-introduction.html">https://cran.r-project.org/web/packages/telegram.bot/vignettes/telegrambot-introduction.html</a></p>



<p><a href="https://chatbotsmagazine.com/building-a-telegram-chatbot-with-r-2754cb75759f">https://chatbotsmagazine.com/building-a-telegram-chatbot-with-r-2754cb75759f</a></p>



<h4 class="wp-block-heading">“Post gerado com framework HUGO (<a href="http://gohugo.io/">http://gohugo.io/</a>), R Markdown (<a href="http://rmarkdown.rstudio.com/">http://rmarkdown.rstudio.com/</a>), no qual os resultados são gerados na geração da página.”</h4>



<p>Post original: </p>



<p><a href="https://jodavid.github.io/post/construindo-um-chatbot-para-telegram-com-r/">https://jodavid.github.io/post/construindo-um-chatbot-para-telegram-com-r/</a></p>



<p>LinkedIndo autor:</p>



<p><a href="https://www.linkedin.com/in/jodavidferreira/">https://www.linkedin.com/in/jodavidferreira/</a></p>
<p>O post <a href="http://estatidados.com.br/construindo-um-chatbot-para-telegram-com-r/">Construindo um ChatBot para Telegram com R</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/construindo-um-chatbot-para-telegram-com-r/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Introdução a Web Scraping com R</title>
		<link>http://estatidados.com.br/introducao-a-web-scraping-com-r/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducao-a-web-scraping-com-r</link>
					<comments>http://estatidados.com.br/introducao-a-web-scraping-com-r/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 18 Jan 2021 15:36:08 +0000</pubDate>
				<category><![CDATA[Estatística]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=535</guid>

					<description><![CDATA[<p>Venho mostrar nesse post, uma introdução sobre Web Scraping com R. O estudo será realizado sobre o projeto “SERENATA DE AMOR”&#160;https://serenata.ai/, que é um projeto aberto no qual usa data science (ciência de dados) &#8211; a mesma tecnolgia usada por<a class="leiamais" href="http://estatidados.com.br/introducao-a-web-scraping-com-r/" title="Introdução a Web Scraping com R">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/introducao-a-web-scraping-com-r/">Introdução a Web Scraping com R</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Venho mostrar nesse post, uma introdução sobre Web Scraping com R.</p>



<p>O estudo será realizado sobre o projeto “SERENATA DE AMOR”&nbsp;<a href="https://serenata.ai/">https://serenata.ai/</a>, que é um projeto aberto no qual usa data science (ciência de dados) &#8211; a mesma tecnolgia usada por gigantes como Google, Facebook e Netflix &#8211; com o objetivo de monitorar os gastos públicos e compartilhar informações de forma acessível a todos.</p>



<p>Até a data da publicação deste post, o projeto já reportou mais de 8.276 ressarcimentos suspeitos à Câmara dos Deputados envolvendo 735 parlamentares diferentes com valor total superior a R$ 3,6 mi.</p>



<p>Quer saber como funciona o sistema de relatórios?&nbsp;<a href="https://medium.com/data-science-brigade/como-est%C3%A1-acontecendo-a-hackaton-de-den%C3%BAncias-da-opera%C3%A7%C3%A3o-serenata-de-amor-a8bd193e0c76">Você pode ler mais neste post &#8211; clicando aqui!</a>.</p>



<p>Explicado o projeto Serenata, voltamos ao Web Scraping. A coleta de dados será sobre o&nbsp;<a href="https://jarbas.serenata.ai/dashboard/chamber_of_deputies/reimbursement/">Jarbas</a>&nbsp;), que é a plataforma onde ficam armazenados os documentos considerados suspeitos. Com o intuito de mostrar que é possível analisar os dados da forma que desejar para tomada de decisões, um gráfico será gerado com os dados coletados de alguns deputados e os valores de reembolso solicitados por eles.</p>



<p>Passo 1: Lendo a URL.</p>



<p>Para ler a página em html, será utilizado a função “read_html” do pacote&nbsp;<em>rvest</em>.</p>



<pre class="wp-block-code"><code>library(rvest)</code></pre>



<pre class="wp-block-code"><code>## Carregando pacotes exigidos: xml2</code></pre>



<pre class="wp-block-code"><code>url &lt;- "https://jarbas.serenata.ai/dashboard/chamber_of_deputies/reimbursement/"
jarbas_webpage &lt;- read_html(url)</code></pre>



<p>Passo 2: Agora, a melhor parte da biblioteca rvest é que você pode extrair os dados de html em forma de nós, o que significa que você pode selecionar imediatamente quais os nós através dos ids ou classes css e extrair o texto das tags do html. Então eu fui para o meu url e abri o “<em>firebug&nbsp;</em>” no navegador e percebi que os nomes dos deputados foram encapsulados na classe css “<em>.field-congressperson_name&nbsp;</em>”, usando esta classe css que posso extrair todos os nomes dos deputados na página da web.</p>



<p>Existem 2 funções que usaremos aqui:</p>



<ol class="wp-block-list"><li>html_nodes: Use esta função para extrair os nós que desejamos (neste caso nós com “.field-congressperson_name” como classe css</li><li>html_text: Use esta função para extrair o texto entre dos nós html (neste caso, os nomes de nossos representantes)</li></ol>



<pre class="wp-block-code"><code>#Scraping  usando classe css ‘field-congressperson_name’
jarbas_names_html &lt;-html_nodes(jarbas_webpage, '.field-congressperson_name')
jarbas_names &lt;- html_text(jarbas_names_html)
head(jarbas_names)</code></pre>



<pre class="wp-block-code"><code>## &#91;1] "Valmir Assunção" "Hélio Leite"     "Hélio Leite"     "Hélio Leite"    
## &#91;5] "Bacelar"         "Hélio Leite"</code></pre>



<p>Da mesma forma, agora farei isso para todos os outros atributos: SUBQUOTA TRANSLATED, FORNECEDOR. Cada um desses atributos tem suas próprias classes css: field-subquota_translated, field-supplier_info.</p>



<pre class="wp-block-code"><code>#SUBQUOTA TRANSLATED
jarbas_subquota_html &lt;-html_nodes(jarbas_webpage, '.field-subquota_translated')
jarbas_subquota &lt;- html_text(jarbas_subquota_html)
head(jarbas_subquota)</code></pre>



<pre class="wp-block-code"><code>## &#91;1] "Combustíveis e lubrificantes"                
## &#91;2] "Divulgação da atividade parlamentar"         
## &#91;3] "Divulgação da atividade parlamentar"         
## &#91;4] "Combustíveis e lubrificantes"                
## &#91;5] "Consultorias, pesquisas e trabalhos técnicos"
## &#91;6] "Combustíveis e lubrificantes"</code></pre>



<pre class="wp-block-code"><code>#Fornecedor
jarbas_provider_html &lt;-html_nodes(jarbas_webpage, '.field-supplier_info')
jarbas_provider &lt;- html_text(jarbas_provider_html)
head(jarbas_provider)</code></pre>



<pre class="wp-block-code"><code>## &#91;1] "POSTO MK 107 NORTE LTDA05.625.571/0001-35"                        
## &#91;2] "PRISCILLA DE CASSIA PORTELA VINHOTE 7054665724934.314.072/0001-25"
## &#91;3] "M SANTOS GUIMARAES EIRELI23.936.281/0001-94"                      
## &#91;4] "SUPER POSTO PALMEIRA LTDA83.838.839/0001-20"                      
## &#91;5] "NARCISO COELHO E MATOS ADVOGADOS ASSOCIADOS17.359.366/0001-54"    
## &#91;6] "Posto de Combustiveis Garantia Ltda72.578.438/0002-43"</code></pre>



<p>A seguir serão mostrados o valor do reembolso, note que eles são extraídos em tipo de variável caracter: Ex: R$ 139,76, R$ 40,23. Entretanto, como desejamos manipular esses números, precisamos convertê-los para tipo de variável numérica, dessa forma será utilizado a biblioteca: “<em>Stringr</em>” mais especificamente a função:&nbsp;<code>str_extract</code>. Segue o script para conversão da variável.</p>



<pre class="wp-block-code"><code>library(stringr)
#valores em Real
jarbas_value_html &lt;-html_nodes(jarbas_webpage, '.field-value')
jarbas_value &lt;- html_text(jarbas_value_html)
head(jarbas_value)</code></pre>



<pre class="wp-block-code"><code>## &#91;1] "R$ 198,84"   "R$ 900,00"   "R$ 300,00"   "R$ 5022,28"  "R$ 13000,00"
## &#91;6] "R$ 168,94"</code></pre>



<pre class="wp-block-code"><code>#R$ 139,76" "R$ 40,23"  "R$ 72,05"  "R$ 72,05"  "R$ 56,39"  "R$ 235,64"  
#dados extraídos na forma de caracter, vamos converter para tipo numérico
jarbas_value &lt;- as.numeric(sub(",",".",str_extract(jarbas_value,pattern = "\\-*\\d+,\\s{0,}\\d+")))
head(jarbas_value,25)</code></pre>



<pre class="wp-block-code"><code>##  &#91;1]   198.84   900.00   300.00  5022.28 13000.00   168.94   600.65   129.17
##  &#91;9]    88.42    26.54   800.62    64.84   164.00    25.84  1817.62   199.35
## &#91;17]  1889.55    64.45    60.40  2214.45   139.32    25.65  3000.00  5000.00
## &#91;25]  1500.00</code></pre>



<p>Passo 3: Com essas informações disponíveis, vamos gerar um dataframe. Para facilitar a visualização, apenas o primeiro nome de cada deputado foi selecionado.</p>



<pre class="wp-block-code"><code>#Combinando todas as características obtidas
jarbas_names &lt;- str_extract(jarbas_names,pattern = boundary("word"))
jarbas_df &lt;- data.frame(
  Name = jarbas_names,
  Subquota = jarbas_subquota,
  Provider = jarbas_provider,
  Value = jarbas_value
  )
str(jarbas_df)</code></pre>



<pre class="wp-block-code"><code>## 'data.frame':    100 obs. of  4 variables:
##  $ Name    : chr  "Valmir" "Hélio" "Hélio" "Hélio" ...
##  $ Subquota: chr  "Combustíveis e lubrificantes" "Divulgação da atividade parlamentar" "Divulgação da atividade parlamentar" "Combustíveis e lubrificantes" ...
##  $ Provider: chr  "POSTO MK 107 NORTE LTDA05.625.571/0001-35" "PRISCILLA DE CASSIA PORTELA VINHOTE 7054665724934.314.072/0001-25" "M SANTOS GUIMARAES EIRELI23.936.281/0001-94" "SUPER POSTO PALMEIRA LTDA83.838.839/0001-20" ...
##  $ Value   : num  199 900 300 5022 13000 ...</code></pre>



<p>Passo 4: Numa primeira análise, podemos utilizar gráfico entre o valor do reembolso e o nome dos deputados. Foram utilizados as 50 primeiras linhas do data.frame e uma biblioteca&nbsp;<em>ggplot2</em>&nbsp;para geração do gráfico.</p>



<pre class="wp-block-preformatted">library(ggplot2)

jarbas_df <- jarbas_df[1:50,]

ggplot(
  jarbas_df, aes(Value,Name,colour=Subquota)) +
  geom_point() +
  labs(title="", x ="pedidos de reembolso (R$)",
       y = "deputados",colour="SUBQUOTA TRANSLATED")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://jodavid.github.io/post/2021-01-09-introdu%C3%A7%C3%A3o-a-web-scrapping-com-r_files/figure-html/unnamed-chunk-6-1.png" alt=""/></figure>



<h4 class="wp-block-heading">“Post gerado com framework HUGO (<a href="http://gohugo.io/">http://gohugo.io/</a>), R Markdown (<a href="http://rmarkdown.rstudio.com/">http://rmarkdown.rstudio.com/</a>), no qual os resultados são gerados na geração da página.”</h4>



<p>Post original:</p>



<p><a href="https://jodavid.github.io/post/web-scraping-introduction-with-r/">https://jodavid.github.io/post/web-scraping-introduction-with-r/</a></p>



<p>LinkedIn do autor:</p>



<p><a href="https://www.linkedin.com/in/jodavidferreira/">https://www.linkedin.com/in/jodavidferreira/</a></p>



<p>#webscraping #R #dadosweb #extrairdados</p>
<p>O post <a href="http://estatidados.com.br/introducao-a-web-scraping-com-r/">Introdução a Web Scraping com R</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/introducao-a-web-scraping-com-r/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Chamando o R do PostgreSQL</title>
		<link>http://estatidados.com.br/chamando-o-r-do-postgresql/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=chamando-o-r-do-postgresql</link>
					<comments>http://estatidados.com.br/chamando-o-r-do-postgresql/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 18 Jan 2021 15:04:49 +0000</pubDate>
				<category><![CDATA[ciencia de dados]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=529</guid>

					<description><![CDATA[<p>Como instalar os dois e usá-los de forma integrada. AUTHOR José de Jesus Filho PUBLISHED Jan. 3, 2021 Introdução Este tutorial irá mostrar como instalar o&#160;R&#160;e o&#160;PostgreSQL&#160;num mesmo servidor Ubuntu 20.04 ou 18.04. Em seguida, falaremos sobre como chamar o<a class="leiamais" href="http://estatidados.com.br/chamando-o-r-do-postgresql/" title="Chamando o R do PostgreSQL">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/chamando-o-r-do-postgresql/">Chamando o R do PostgreSQL</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="678" src="http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-1024x678.png" alt="" class="wp-image-530" srcset="http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-1024x678.png 1024w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-300x199.png 300w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-768x508.png 768w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-200x132.png 200w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-378x250.png 378w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-400x265.png 400w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-1000x662.png 1000w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot-718x475.png 718w, http://estatidados.com.br/wp-content/uploads/2021/01/linear_plot.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Como instalar os dois e usá-los de forma integrada.</p>



<h3 class="wp-block-heading">AUTHOR</h3>



<p><a href="https://rpg.consudata.com.br/">José de Jesus Filho</a></p>



<h3 class="wp-block-heading">PUBLISHED</h3>



<p>Jan. 3, 2021</p>



<h2 class="wp-block-heading" id="introdução">Introdução</h2>



<p>Este tutorial irá mostrar como instalar o&nbsp;<em>R</em>&nbsp;e o&nbsp;<em>PostgreSQL</em>&nbsp;num mesmo servidor Ubuntu 20.04 ou 18.04. Em seguida, falaremos sobre como chamar o R a partir do PostgreSQL.</p>



<p>Farei uma série de tutoriais. Este primeiro é voltado para aqueles com familiaridade com funções do R e que gostariam de rodá-las no PostgreSQL, sem necessariamente conhecer muito de SQL. Num próximo, iremos mostrar como criar queries e declarações do PostgreSQL do R, ou seja, será mais voltado para quem tem familiaridade com o SQL, mas não necessariamente versada em R.</p>



<p>Os tutoriais posteriores serão voltados para aqueles com bastante familiaridade em tidyverse e que gostariam de realizar as mesmas coisas em SQL. Igualmente, servirão para aqueles que sabem manipular dados em SQL, mas gostariam de fazer as mesmas coisas no R.</p>



<p>Em futuros tutoriais, falaremos quando compensa iniciar no PostgreSQL e terminar no R. Por exemplo, quando é mais vantajoso dar um join no R em vez de fazê-lo no PostgreSQL e vice-versa.</p>



<h2 class="wp-block-heading" id="instalando-o-postgresql">Instalando o PostgreSQL</h2>



<p>A primeira coisa a fazer é atualizar os pacotes do sistema:</p>



<pre class="wp-block-code"><code>sudo apt update
sudo apt -y install vim bash-completion wget
sudo apt -y upgrade


### Configuração do locale

Além disso, é importante configurar o locale. Crie um arquivo chamado set_locale.sh:

```sh
$ vim set_locale.sh</code></pre>



<p>E cole o seguinte conteúdo:</p>



<pre class="wp-block-code"><code>#!/bin/bash

# Set locales in /etc/default/locale file
echo "Ajustando o locale..."
echo "# Locale settings
export LANGUAGE=pt_BR.UTF-8
export LANG=pt_BR.UTF-8
export LC_ALL=pt_BR.UTF-8">>~/.bash_profile

locale-gen pt_BR.UTF-8

sudo dpkg-reconfigure locales

source ~/.bash_profile</code></pre>



<p>autorize execução do arquivo:</p>



<pre class="wp-block-code"><code>$ sudo chmod +x set_locale.sh</code></pre>



<p>E rode o script:</p>



<pre class="wp-block-code"><code>$ sudo ./set_locale.sh</code></pre>



<p>Reinicie a máquina:</p>



<pre class="wp-block-code"><code>$ sudo reboot</code></pre>



<p>Acesse novavamente via ssh e verifique se o locale foi configurado para&nbsp;<code>pt_BR-UTF8</code>.</p>



<pre class="wp-block-code"><code>$ locale</code></pre>



<p>O console deverá imprimir a seguinte configuração:</p>



<pre class="wp-block-code"><code>LANG=pt_BR.UTF-8
LANGUAGE=pt_BR.UTF-8
LC_CTYPE="pt_BR.UTF-8"
LC_NUMERIC="pt_BR.UTF-8"
LC_TIME="pt_BR.UTF-8"
LC_COLLATE="pt_BR.UTF-8"
LC_MONETARY="pt_BR.UTF-8"
LC_MESSAGES="pt_BR.UTF-8"
LC_PAPER="pt_BR.UTF-8"
LC_NAME="pt_BR.UTF-8"
LC_ADDRESS="pt_BR.UTF-8"
LC_TELEPHONE="pt_BR.UTF-8"
LC_MEASUREMENT="pt_BR.UTF-8"
LC_IDENTIFICATION="pt_BR.UTF-8"
LC_ALL=pt_BR.UTF-8</code></pre>



<p>Como última etapa, configure também o fuso horário:</p>



<pre class="wp-block-code"><code>$ sudo timedatectl set-timezone America/Sao_Paulo</code></pre>



<p>Confirme que o fuso horário foi configurado para São Paulo:</p>



<pre class="wp-block-code"><code>$ timedatectl</code></pre>



<p>Você deverá visualizar o seguinte resultado:</p>



<pre class="wp-block-code"><code>Local time: Qua 2020-06-17 19:34:30 -03
  Universal time: Qua 2020-06-17 22:34:30 UTC
        RTC time: Qua 2020-06-17 22:34:30
       Time zone: America/Sao_Paulo (-03, -0300)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no</code></pre>



<p>Importe a chave GPG:</p>



<pre class="wp-block-code"><code>wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -</code></pre>



<p>Adicione a chave GPG ao systema:</p>



<pre class="wp-block-code"><code>echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee  /etc/apt/sources.list.d/pgdg.list</code></pre>



<p>Atualize os pacotes do sistema e instale os pacotes do PostgreSQL necessários. Os dois primeiros são necessários para rodar o PostgreSQL, os três últimos são necessários para instalar o&nbsp;<code>plr</code>, o RPostgres e outras extensões. Falaremos deles mais adiante.</p>



<pre class="wp-block-code"><code>sudo apt update
sudo apt install postgresql-12 postgresql-client-12 postgresql-server-dev-all libpq-dev postgresql-contrib</code></pre>



<h2 class="wp-block-heading" id="instalação-do-r">Instalação do R</h2>



<pre class="wp-block-code"><code>sudo echo "deb https://cloud.r-project.org/bin/linux/ubuntu `lsb_release -cs`-cran40/" | sudo tee -a /etc/apt/sources.list</code></pre>



<h3 class="wp-block-heading" id="adicionar-a-chave-gpg">Adicionar a chave GPG</h3>



<pre class="wp-block-code"><code>sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9</code></pre>



<h3 class="wp-block-heading" id="instale-o-r">Instale o R</h3>



<pre class="wp-block-code"><code>sudo apt-get update
sudo apt-get install -y r-base r-base-dev </code></pre>



<p>Instale também o git</p>



<pre class="wp-block-code"><code>sudo apt install git</code></pre>



<p>Agora use o git para clonar o plr. Não importa o local onde você irá cloná-lo. Desde que você tenha seguido fielmente os passos anteriores, tudo terminará bem.</p>



<pre class="wp-block-code"><code>git clone https://github.com/postgres-plr/plr</code></pre>



<p>Feito isso, entre no diretório plr e rode os seguintes comandos para instalá-lo como extensão.</p>



<pre class="wp-block-code"><code>cd plr
USE_PGXS=1 make
USE_PGXS=1 make install</code></pre>



<h2 class="wp-block-heading" id="criando-uma-base-de-dados">Criando uma base de dados</h2>



<p>Vamos para o Postgres a fim de criar uma base de dados.</p>



<pre class="wp-block-code"><code>sudo -u postgres psql</code></pre>



<pre class="wp-block-code"><code>CREATE DATABASE datasets;</code></pre>



<p>Além disso, você deve incluir a extensão&nbsp;<code>plr</code>&nbsp;na base de dados recentemente criada:</p>



<pre class="wp-block-code"><code>\c datasets -- conectar-se à base
CREATE EXTENSION plr;
\q -- sair do psql</code></pre>



<p>De volta ao R.</p>



<pre class="wp-block-code"><code>R</code></pre>



<h3 class="wp-block-heading" id="instale-os-pacotes-rpostgres-e-broom">Instale os pacotes&nbsp;<code>RPostgres</code>&nbsp;e&nbsp;<code>broom</code></h3>



<p>Instalando esses dois pacotes é suficiente para instalar também outras dependências como o DBI e o dplyr, as quais igualmente usaremos.</p>



<pre class="wp-block-code"><code>install.packages(c("RPostgres","broom"))</code></pre>



<h2 class="wp-block-heading" id="connexão-do-r-ao-postgres">Connexão do R ao Postgres</h2>



<p>Eventualmente, você terá de autorizar a conexão local. Vá para o arquivo:</p>



<pre class="wp-block-code"><code>vim /etc/postgresql/12/main/pg_hba.conf</code></pre>



<p>E altere a seguinte linha de:</p>



<pre class="wp-block-code"><code>local all all peer</code></pre>



<p>Para:</p>



<pre class="wp-block-code"><code>local all all trust</code></pre>



<h3 class="wp-block-heading" id="colocando-uma-tabela-na-base-de-dados">Colocando uma tabela na base de dados</h3>



<p>Admitindo que você ainda se encontra no R, estamos em condições de incluir uma tabela na base de dados.</p>



<p>Primeiramente, vamos conectar-nos à base:</p>



<pre class="wp-block-code"><code>conn &lt;- DBI::dbConnect(RPostgres::Postgres(), dbname="datasets")</code></pre>



<p>Estou admidindo com o código acima que você está usando o R na mesma máquina do Postgres, usando o usuário&nbsp;<code>postgres</code>&nbsp;e dispensou o uso de senha para conexão local.</p>



<p>Vamos enviar o dataframe mtcars para a base de dados. O exemplo do mtcars não é muito feliz porque ele poderia ser chamado do próprio R quando rodado no Postgres, mas apenas a título de exemplo, iremos assumir que ele seja qualquer outro data.frame.</p>



<pre class="wp-block-code"><code>DBI::dbWriteTable(conn,"tabela", mtcars)</code></pre>



<h2 class="wp-block-heading" id="de-volta-ao-postgres">De volta ao Postgres</h2>



<p>Mostraremos num próximo tutorial como realizar os procedimentos a seguir sem sair do R, mas o propósito deste tutorial é justamente ilustrar como podemos chamar o R do Postgres. Assim, faremos tudo no Postgres mesmo.</p>



<p>Voltando para o shell, vamos conectar-nos à base datasets:</p>



<pre class="wp-block-code"><code>sudo -u postgres psql datasets</code></pre>



<p>Verifique se a tabela chamada “tabela” se encontra na base de dados:</p>



<pre class="wp-block-code"><code>\d+ -- ou 
\d+ tabela</code></pre>



<h2 class="wp-block-heading" id="preparando-o-terreno">Preparando o terreno</h2>



<p>Vamos criar uma tabela que servirá de referência para receber os resultados de uma regressão linear. Veja que as colunas são as mesmas do&nbsp;<code>tibble</code>&nbsp;retornado pela função&nbsp;<code>tidy</code>&nbsp;do pacote&nbsp;<code>broom</code>, com a diferença de que os pontos foram substituídos pelo sublinhado e os nomes das colunas passados para o português.</p>



<pre class="wp-block-code"><code>create table modelo (termo text, estimativa float8, erro_padrao float8, estatistica float8, p_valor float8);</code></pre>



<h3 class="wp-block-heading" id="criando-uma-função-plr">Criando uma função plr</h3>



<p>Enfim estamos em condições de criar uma função no PostgreSQL que chama o R para rodar uma regressão linear em uma tabela contida no próprio Postgres:</p>



<pre class="wp-block-code"><code>CREATE OR REPLACE FUNCTION lm_teste() RETURNS SETOF modelo AS
$$ 
base &lt;&lt;- pg.spi.exec('select mpg, wt, qsec, am  from tabela')
df &lt;- lm(mpg ~ wt + qsec + factor(am), data=base)
df &lt;- broom::tidy(df)
names(df) &lt;- c('termo','estimativa','erro_padrao','estatistica','p_valor')
df &lt;- dplyr::mutate_at(df,dplyr::vars(2:5), ~round(.,2))
return(df)
$$
language 'plr';</code></pre>



<p>Note que o esqueleto da função é o mesmo para qualquer outra função do PostgreSQL. A diferença é que, para importar um objeto da base de dados para nossa função, devemos usar a função&nbsp;<code>pg.spi.exec</code>.</p>



<h2 class="wp-block-heading" id="rodando-a-regressão-linear">Rodando a regressão linear</h2>



<p>Agora ficou fácil. Basta chamar a função e ver os resultados:</p>



<pre class="wp-block-code"><code>select * from lm_teste();</code></pre>



<pre class="wp-block-code"><code>datasets=# select * from lm_teste();
    termo    | estimativa | erro_padrao | estatistica | p_valor
-------------+------------+-------------+-------------+---------
 (Intercept) |       9.62 |        6.96 |        1.38 |    0.18
 wt          |      -3.92 |        0.71 |       -5.51 |       0
 qsec        |       1.23 |        0.29 |        4.25 |       0
 factor(am)1 |       2.94 |        1.41 |        2.08 |    0.05
(4 rows)</code></pre>



<h2 class="wp-block-heading" id="vantagens">Vantagens</h2>



<p>Eu apontaria duas principais vantagens em usar o plr:</p>



<p>1 &#8211; Uma vez que a base se encontra no PostgreSQL, você não precisa mais transferi-la para o R a fim de rodar o modelo e retornar o resultado ao PostgreSQL. Essa viagem dos dados torna-se dispensável. No exemplo mostrado, porém, a base irá para uma sessão do R de qualquer forma. Veremos como solucionar isso em tutoriais futuros.</p>



<p>2 &#8211; Você pode continuar trabalhando no R, enquanto seu modelo roda no PostgreSQL. Se o modelo tomar horas, este se torna um problema menor.</p>



<p>Link da publicação original:</p>



<p><a href="https://rpg.consudata.com.br/posts/2021-01-04-chamando-o-r-do-postgresql/">https://rpg.consudata.com.br/posts/2021-01-04-chamando-o-r-do-postgresql/</a></p>



<p>Linkedin Autor:</p>



<p><a href="https://www.linkedin.com/in/jjesusfilho/">https://www.linkedin.com/in/jjesusfilho/</a></p>



<p>#linguagemdeprogramação #R #SQL #cienciadedados</p>
<p>O post <a href="http://estatidados.com.br/chamando-o-r-do-postgresql/">Chamando o R do PostgreSQL</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/chamando-o-r-do-postgresql/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A utilização do Software R na resolução de problemas na Pesquisa Operacional</title>
		<link>http://estatidados.com.br/a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional</link>
					<comments>http://estatidados.com.br/a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 01 Dec 2020 18:50:46 +0000</pubDate>
				<category><![CDATA[Julio Proença]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Pesquisa Operacional]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=514</guid>

					<description><![CDATA[<p>A Pesquisa Operacional consiste na utilização de métodos científicos para auxiliar a tomada de decisão frente a problemas complexos que exigem alocações eficientes de recursos escassos. A resolução desses problemas se dá por várias etapas, sendo que a modelagem e<a class="leiamais" href="http://estatidados.com.br/a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional/" title="A utilização do Software R na resolução de problemas na Pesquisa Operacional">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional/">A utilização do Software R na resolução de problemas na Pesquisa Operacional</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img decoding="async" width="764" height="569" src="http://estatidados.com.br/wp-content/uploads/2020/12/post.png" alt="" class="wp-image-515" srcset="http://estatidados.com.br/wp-content/uploads/2020/12/post.png 764w, http://estatidados.com.br/wp-content/uploads/2020/12/post-300x223.png 300w, http://estatidados.com.br/wp-content/uploads/2020/12/post-200x149.png 200w, http://estatidados.com.br/wp-content/uploads/2020/12/post-336x250.png 336w, http://estatidados.com.br/wp-content/uploads/2020/12/post-400x298.png 400w, http://estatidados.com.br/wp-content/uploads/2020/12/post-638x475.png 638w" sizes="(max-width: 764px) 100vw, 764px" /></figure>



<p>A Pesquisa Operacional consiste na utilização de métodos científicos para auxiliar a tomada de decisão frente a problemas complexos que exigem alocações eficientes de recursos escassos.</p>



<p>A resolução desses problemas se dá por várias etapas, sendo que a modelagem e a escolha do&nbsp;<em>software</em>&nbsp;para resolução se caracterizam como partes fundamentais para o sucesso da resolução.</p>



<p>Nesse trabalho, vamos utilizar o&nbsp;<em>software</em>&nbsp;R na resolução de problemas de Pesquisa Operacional, especificamente problemas de Programação Linear, modelados ou não por redes.</p>



<p>O objetivo é mostrar que, embora o&nbsp;<em>software</em>&nbsp;R seja utilizado majoritariamente em Matemática e Estatística, ele pode ser uma ferramenta bastante útil na Programação Linear, posto que possui muitas funções associadas à Otimização de forma geral e, além disso, é um&nbsp;<em>software</em>&nbsp;livre e gratuito.</p>



<p><strong>INTRODUÇÃO</strong></p>



<p>A Pesquisa Operacional (PO) surgiu durante a Segunda Guerra Mundial, especificamente na Inglaterra. Um grupo de cientistas foi convocado para determinar uma utilização eficiente de recursos militares limitados e, os resultados positivos obtidos por esses cientistas, fizeram com que a PO fosse difundida para os Estados Unidos, onde ela se desenvolveu de forma consistente. Desde então, essa ciência vem sendo aplicada com sucesso na otimização de recursos em diferentes segmentos (FÁVERO &amp; BELFIORE, 2013).</p>



<p>Segundo Arenales et al. (2011), a PO consiste na utilização de métodos científicos para auxiliar a tomada de decisão frente a problemas complexos que exigem alocações eficientes de recursos escassos (ou seja, problemas de otimização).</p>



<p>De forma simplificada, Marins (2011) propõe a resolução de um problema de PO em cinco etapas:</p>



<p>a) Formulação do problema (identificação do sistema);</p>



<p>b) Construção do modelo matemático;</p>



<p>c) obtenção da solução;</p>



<p>d) teste do modelo e da solução obtida;</p>



<p>e) implementação.</p>



<p>Uma das ferramentas mais utilizadas dentro da PO é a Programação Linear (PL). A PL tem como objeto, essencialmente, encontrar a melhor solução para os problemas que tenham expressões lineares representando seus modelos. Essencialmente, atribui-se a PL a maximização ou minimização de uma função linear (função objetivo), satisfazendo as restrições do modelo (sistema linear de igualdades ou desigualdades).</p>



<p>Incorporado a programação linear pode-se ressaltar o método simplex, que é uma técnica utilizada para se determinar, numericamente a solução ótima para um determinado modelo.</p>



<p>É necessário utilizar-se de software para a resolução de problemas de programação linear, pois a maioria dos impasses podem apresentar funções de várias variáveis, tornando-se assim inviável a solução de tal problema sem o auxílio dos softwares. Contudo, grande parte desses softwares apresentam código fechado, isto é, seu acesso é restrito, deixando de apresentar para o usuário uma solução de forma didática (MARINS, 2011).</p>



<p>Para a resolução dessa modelagem, vários softwares foram desenvolvidos, como: LINDO, CPLEX, PROMODEL, ARENA e Solver do Excel. Porém, tais programas não possuem código livre e não são gratuitos, limitando seu acesso e utilização.</p>



<p>Dessa forma, esse estudo tem como objetivo mostrar a utilização de softwares livres e gratuitos para a resolução de problemas de pesquisa operacional, especificamente problemas de programação linear. Nesse caso, mostrar a potencialidade do software R para a resolução de problemas aplicados pesquisa operacional.</p>



<p><strong><em>Software</em>&nbsp;R</strong></p>



<p>O&nbsp;<em>software</em>&nbsp;R (R CORE TEAM, 2018), que surge pela criação da&nbsp;<em>R Foundation for Statistical Computing</em>, além de um tipo de linguagem, é um software computacional e gráfico, que tem como vantagens a gratuidade, código aberto e livre acesso, para que inúmeros usuários desenvolvam novos comandos e de forma que possam compartilhar em redes sociais (RSTUDIO, 2020).</p>



<p>Além disso, o programa oferece uma gama de funções, podendo adaptá-la de acordo com suas necessidades.</p>



<p>O R tem compatibilidade com diversas plataformas, como&nbsp;<em>LINUX</em>&nbsp;e&nbsp;<em>Windows</em>, e permite a ligação de interfaces de diferentes formatos, como&nbsp;<em>Excel</em>&nbsp;e&nbsp;<em>SQL Server</em>. Sendo fonte aberta, permite ao utilizador alterar funcionalidades existentes, bem como criar funcionalidades para responder aos seus problemas específicos de forma mais eficaz (LIMA et al., 2015). &nbsp;</p>



<p>Atualmente, o&nbsp;<em>software</em>&nbsp;R não é o meio de resolução de problema de pesquisa operacional e programação linear mais utilizado, pois há uma cultura de que o&nbsp;<em>EXCEL (Solver)</em>&nbsp;tenha usabilidade mais fácil e prática que o R (RSTUDIO, 2020).</p>



<p>Entretanto, o R oferece diversas opções de pacotes (conjuntos de funções) para resolver problemas de Pesquisa Operacional, como&nbsp;<em>orloca</em>,&nbsp;<em>linprog</em>,&nbsp;<em>quadprog</em>, BB,&nbsp;<em>boot</em>,&nbsp;<em>kernlab</em>,&nbsp;<em>limSolve</em>,&nbsp;<em>LowRankQP</em>,&nbsp;<em>rcdd</em>,&nbsp;<em>Rglpk</em>, entre outros (LIMA et al., 2015). &nbsp;</p>



<p><strong>Resolução de um problema de Pesquisa Operacional utilizando o Software R</strong></p>



<p>O problema proposto a seguir é denominado Caso LCL Motores Ltda. É um exemplo que mostra uma das típicas situações enfrentadas no dia a dia por diversas empresas (LACHTERMACHER, 2009).</p>



<p>Para resolver o exemplo proposto, foi utilizado o pacote&nbsp;<em>lpSolve</em>&nbsp;(Berkelaar, 2020).</p>



<p><strong>Problema:</strong>&nbsp;A LCL Motores Ltda. uma fábrica de motores especiais recebeu recentemente R$ 900.000.00 em pedidos de seus três tipos de motores. Cada motor necessita de um determinado número de horas de trabalho no setor de montagem e acabamento. A LCL pode terceirizar parte da sua produção. A tabela abaixo resume estes dados. A LCL Motores deseja determinar quanto motores devem ser produzidos em sua fábrica e quantos devem ser produzidos de forma terceirizada para atender à demanda de pedidos.</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQEFlUD6-B5_bw/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=HuaxfhqXnfCx35Gn59_khzbXcD8xb1epUe8EnpdZVcs" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p><strong>Solução:</strong></p>



<p>O primeiro passo para a modelagem é a determinação das variáveis de decisão. Neste caso, o objetivo é determinar a quantidade de motores de cada tipo que deve ter sua produção terceirizada. Sendo assim, as variáveis são:</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQFgRVWqAuZFUg/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=_87aw5MG6eJKu6hd-TXyjzJdDsTUC-aWVwl1BLO_fM0" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>O segundo passo é determinar a expressão da função objetivo. Neste caso, a empresa deseja maximizar seus lucros. Ou seja,</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQEzPWXr3CrgWA/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=QL6K8vaGExMyDdprmDlBlxYyWBJE0bKU9h-o883HiTQ" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Equivalentemente, pode-se escrever a função como:</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQFZV7df3dQFUA/article-inline_image-shrink_1000_1488/0/1601318941039?e=1612396800&amp;v=beta&amp;t=vTfTgg_AMql47WpR02vz7XOXCDXHK1WJmhVoqDxwAsw" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Por fim, deve-se determinar as restrições que se aplicam ao modelo. Estas restrições estão relacionadas aos recursos da empresa e são descritas a seguir:</p>



<p>1) Restrição de Montagem</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQHdm_mfDS-O_w/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=OOUnbemukPix-FUtlXOp0HnOkMrkU03zVz1DySXg4lo" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>2) Restrição do Acabamento</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQH9EoQZDwQezw/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=jDA_gRJd0isizjd4fOpzP0PX04oJ4NPX0-RMHUNCRXw" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>3) Restrições de Demanda</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQGrQAD-AFUwZg/article-inline_image-shrink_1000_1488/0/1601319257609?e=1612396800&amp;v=beta&amp;t=21fzyWNH_D2qGG0_O6gbZs6DouczIHBWUCEnH3xXaOw" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>O nosso problema pode ser resumido na seguinte modelagem:</p>



<p>Sujeito a:</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQEdKvPWlGOFGQ/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=IwYWDSj2A99Kb0jxSa8nn4t6nFDr-nnCd2S0Rn99p1w" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Figura 1: Instalação do pacote&nbsp;<em>lpSolve:</em></p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQEg6aL2o2W9CA/article-inline_image-shrink_1000_1488/0/1601318390361?e=1612396800&amp;v=beta&amp;t=TQGlcwmz3aWscH8BUYnnnYzu4xG5dWFPYheJD7VVVP0" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Figura 2:&nbsp;<em>Script</em>&nbsp;da resolução do problema no&nbsp;<em>software</em>&nbsp;R</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQHnuxaw4q9MHw/article-inline_image-shrink_1000_1488/0/1601318454734?e=1612396800&amp;v=beta&amp;t=9_TY1soFF3WQNplnDV0ZLbCoghjs8nAWhkH36zXePDM" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Figura 3:&nbsp;<em>Script&nbsp;</em>da resolução do problema no&nbsp;<em>software</em>&nbsp;R</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQGzriu2h6yhMA/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=I_R1ECF8fmsv62Z6YHuXB6d4ZeZ3umgttrcOW5QObAM" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Figura 4: Valor das variáveis de decisão e da função objetivo do problema proposto</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4E12AQGQpvDtJOplIw/article-inline_image-shrink_1000_1488/0?e=1612396800&amp;v=beta&amp;t=Zdpgl8lzAEIcsBpteSiBfNFi-Zogc8L5h5QuV_3GeiE" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Na Figura 1, encontra-se a forma de instalação dos pacotes do R. Quando o&nbsp;<em>software</em>&nbsp;é instalado, apenas as configurações mínimas são instaladas. Um dado pacote deve ser pesquisado em&nbsp;<em>packages</em>&nbsp;e instalado para seu total funcionamento.</p>



<p>Na Figura 2, tem-se o&nbsp;<em>script</em>&nbsp;do R para resolução do problema proposto. Para utilizar o pacote&nbsp;<em>lpSolve</em>&nbsp;com a função&nbsp;<em>lp</em>&nbsp;é necessário definir:</p>



<p>a) Função objetivo;</p>



<p>b) Matriz de restrições;</p>



<p>c) Tipos de desigualdades;</p>



<p>d) Lado direito das desigualdades ou limites</p>



<p>Todos os elementos na programação do R (vetores, matrizes,&nbsp;<em>data frame</em>) podem ser arquivados por meio do sinal “&lt;-“.</p>



<p>Ainda pela Figura 2, nota-se que para os elementos “coef_func_objetivo”, “coef_restricoes”, “sinais_restricoes” e “limites_restricoes” ficam atribuídos, respectivamente, o vetor de coeficientes da função objetivo, a matriz dos coeficientes das restrições, os sinais associados às restrições e os limites numéricos das restrições.</p>



<p>Para entender a função&nbsp;<em>lp</em>&nbsp;do pacote&nbsp;<em>lpSolve,</em>&nbsp;o R fornece a descrição de todas suas funções no&nbsp;<em>Help</em>. Todos os argumentos e as formas corretas para considerar as informações são encontradas nesse tópico, além de exemplos que ilustram a utilização da função. Pode-se observar na Figura 3, o item de ajuda do&nbsp;<em>software</em>&nbsp;R.</p>



<p>Na Figura 4, encontra-se os valores da função objetivo e das variáveis de decisão do problema proposto. Conclui-se que, para o custo mínimo de R$ 439000, a empresa deve terceirizar a produção de 2000 motores do modelo 2 e produzir 3000, 5000 e 500 motores dos modelos 1, 2 e 3, respectivamente</p>



<p><strong>Conclusão</strong></p>



<p>O&nbsp;<em>software</em>&nbsp;R é uma importante ferramenta utilizada na resolução de problemas de Estatística e Matemática. Porém, esse&nbsp;<em>software</em>&nbsp;possui diversos tipos de pacotes que contêm funções capazes de resolver problemas dos mais diversos assuntos. Dentre esses problemas, pode-se incluir a Pesquisa Operacional e, em particular, a Programação Linear e Não Linear.</p>



<p>Conforme abordado acima, o&nbsp;<em>software</em>&nbsp;R apresenta uma série de vantagens para a pesquisa operacional e com o desenvolver do estudo é possível concluir que o programa é de fácil manuseio, além de trazer funções diversas que outros softwares mais populares não possuem. Além disso, pode-se dizer que o&nbsp;<em>software</em>&nbsp;R oferece auxílio suficiente para um aprendizado autodidata, posto que sua função de ajuda é bastante detalhada e informativa, com exemplos e explicações detalhadas das funções.</p>



<p>Portanto, o estudo apresentado tem importância associada à formação de um engenheiro de produção, pois permite a utilização de um software livre e de fácil aplicação mesmo em problemas de difícil solução, aumentando as possibilidades de ferramentas que podem ser utilizadas por um profissional completo.</p>



<p>Autor: Julio César Proença da Costa</p>



<p>Linkedin: https://www.linkedin.com/in/julio-proen%C3%A7a-43499315b/</p>



<p>#R #pesquisaoperacional #metódodedecisão</p>
<p>O post <a href="http://estatidados.com.br/a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional/">A utilização do Software R na resolução de problemas na Pesquisa Operacional</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/a-utilizacao-do-software-r-na-resolucao-de-problemas-na-pesquisa-operacional/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Utilizando o R para obter decretos relacionados ao COVID-19 no Brasil</title>
		<link>http://estatidados.com.br/utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil</link>
					<comments>http://estatidados.com.br/utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 30 Sep 2020 12:32:58 +0000</pubDate>
				<category><![CDATA[Cleiton Rocha]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=446</guid>

					<description><![CDATA[<p>Introdução No Brasil, diante da emergência sanitária mundial, as autoridades estabeleceram diversas portarias/decretos com regras e normas para funcionamento de serviços de saúde e serviços não essenciais. Na maioria das unidades da federação, as aulas na rede pública e na<a class="leiamais" href="http://estatidados.com.br/utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil/" title="Utilizando o R para obter decretos relacionados ao COVID-19 no Brasil">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil/">Utilizando o R para obter decretos relacionados ao COVID-19 no Brasil</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="http://estatidados.com.br/wp-content/uploads/2020/09/1_oi17URjs9Oy7cTH9zMzMlw.png" alt="" class="wp-image-447" width="893" height="412" srcset="http://estatidados.com.br/wp-content/uploads/2020/09/1_oi17URjs9Oy7cTH9zMzMlw.png 814w, http://estatidados.com.br/wp-content/uploads/2020/09/1_oi17URjs9Oy7cTH9zMzMlw-300x139.png 300w, http://estatidados.com.br/wp-content/uploads/2020/09/1_oi17URjs9Oy7cTH9zMzMlw-200x93.png 200w, http://estatidados.com.br/wp-content/uploads/2020/09/1_oi17URjs9Oy7cTH9zMzMlw-400x185.png 400w" sizes="auto, (max-width: 893px) 100vw, 893px" /></figure>



<h1 class="wp-block-heading" id="a45a">Introdução</h1>



<p>No Brasil, diante da emergência sanitária mundial, as autoridades estabeleceram diversas portarias/decretos com regras e normas para funcionamento de serviços de saúde e serviços não essenciais.</p>



<p>Na maioria das unidades da federação, as aulas na rede pública e na rede privada foram suspensas. Eventos com grande número de pessoas foram proibidos. Houve mudanças no transporte público, com redução de frota, e alterações nas regras de abertura de comércios, bares, restaurantes e shoppings.</p>



<p>O objetivo dessas restrições era de evitar a sobrecarga dos serviços de saúde e esgotamento dos leitos de tratamento, à medida que, a União, Estados e Municípios poderiam se preparar para o aumento no número de casos com a construção de hospitais de campanha e importação de respiradores.</p>



<p>Ao longo dos últimos meses os decretos vêm sendo moldados de acordo com a realidade da pandemia no país. Mudanças como aumento das restrições de circulação e expansão na oferta de crédito, foram mais recentemente transformadas em medidas de reabertura de algumas atividades econômicas com estruturas e horários de funcionamento diferenciados, entre outros tipos. Uma forma de olhar o panorama do Covid-19 no país é observando como os agentes políticos legislaram a respeito do tema.</p>



<p>No texto a seguir explico como gerar um banco de dados no R com informações atualizadas sobre os decretos nos níveis municipal, estadual e federal, com registro da data, sua classificação em decreto ou lei e algumas outras informações.</p>



<p>Vamos lá!</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="5008">Carregando os dados e os pacotes no R</h1>



<p>A fonte dos dados vem do site&nbsp;<a href="https://leismunicipais.com.br/">https://leismunicipais.com.br/</a>, que é totalmente confiável, tanto que vários municípios utilizam a ferramenta. Você pode encontrar mais informações sobre eles&nbsp;<a href="https://leismunicipais.com.br/institucional">aqui</a>.</p>



<p>O ‘Leis Municipais’ vem mantendo uma&nbsp;<a href="https://leismunicipais.com.br/coronavirus">página</a>&nbsp;com dados sobre os decretos relacionados ao Covid-19, é dessa página que vamos extrair as informações, de dentro do R, é claro.</p>



<pre class="wp-block-preformatted"># Pacotes<br>library(dplyr)<br>library(tidyr)<br>library(purrr)<br>library(xml2)<br>library(stringr)<br>library(rvest)<br>library(mgsub)<br>library(gsubfn)<br>library(lubridate)# Pasta de trabalho - altere o caminho para onde os arquivos serão salvos #<br>setwd("C:\\Users\\pc\\Desktop\\Cidacs\\ETL")########################################################<br>#### DECRETOS POR ESTADO<br>########################################################Acre &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=AC">https://leismunicipais.com.br/coronavirus?estado=AC</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Acre")Alagoas &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=AL">https://leismunicipais.com.br/coronavirus?estado=AL</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Alagoas")Amapá &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=AP">https://leismunicipais.com.br/coronavirus?estado=AP</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F)  %&gt;% mutate(Estado = "Amapá")Amazonas &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=AM">https://leismunicipais.com.br/coronavirus?estado=AM</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Amazonas")Bahia&lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=BA">https://leismunicipais.com.br/coronavirus?estado=BA</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Bahia")Ceará &lt;-read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=CE">https://leismunicipais.com.br/coronavirus?estado=CE</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Ceará")Distrito_Federal&lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=DF">https://leismunicipais.com.br/coronavirus?estado=DF</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Distrito Federal")Espírito_Santo &lt;-read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=ES">https://leismunicipais.com.br/coronavirus?estado=ES</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Espírito Santo")Goiás &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=GO">https://leismunicipais.com.br/coronavirus?estado=GO</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Goiás")Maranhão &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=MA">https://leismunicipais.com.br/coronavirus?estado=MA</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Maranhão")Mato_Grosso &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=MT">https://leismunicipais.com.br/coronavirus?estado=MT</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Mato Grosso")Mato_Grosso_do_Sul &lt;-read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=MS">https://leismunicipais.com.br/coronavirus?estado=MS</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Mato Grosso do Sul")Minas_Gerais &lt;- read.csv2<br>("<a href="https://leismunicipais.com.br/coronavirus?estado=MG">https://leismunicipais.com.br/coronavirus?estado=MG</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Minas Gerais")Pará &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=PA">https://leismunicipais.com.br/coronavirus?estado=PA</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Pará")Paraíba  &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=PB">https://leismunicipais.com.br/coronavirus?estado=PB</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Paraíba")Paraná  &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=PR">https://leismunicipais.com.br/coronavirus?estado=PR</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F)  %&gt;% mutate(Estado = "Paraná")Pernambuco &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=PE">https://leismunicipais.com.br/coronavirus?estado=PE</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F)  %&gt;% mutate(Estado = "Pernambuco")Piauí &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=PI">https://leismunicipais.com.br/coronavirus?estado=PI</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F)  %&gt;% mutate(Estado = "Piauí")Rio_de_Janeiro &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=RJ">https://leismunicipais.com.br/coronavirus?estado=RJ</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Rio de Janeiro")Rio_Grande_do_Norte &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=RN">https://leismunicipais.com.br/coronavirus?estado=RN</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Rio Grande do Norte")Rio_Grande_do_Sul  &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=RS">https://leismunicipais.com.br/coronavirus?estado=RS</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F)  %&gt;% mutate(Estado = "Rio Grande do Sul")Rondônia &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=RO">https://leismunicipais.com.br/coronavirus?estado=RO</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Rondônia")Roraima &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=RR">https://leismunicipais.com.br/coronavirus?estado=RR</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Roraima")Santa_Catarina  &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=SC">https://leismunicipais.com.br/coronavirus?estado=SC</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Santa Catarina")São_Paulo &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=SP">https://leismunicipais.com.br/coronavirus?estado=SP</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F)  %&gt;% mutate(Estado = "São Paulo")Sergipe &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=SE">https://leismunicipais.com.br/coronavirus?estado=SE</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Sergipe")Tocantins &lt;- read.csv2("<a href="https://leismunicipais.com.br/coronavirus?estado=TO">https://leismunicipais.com.br/coronavirus?estado=TO</a>", encoding =  'UTF-8', sep=",", stringsAsFactors = F) %&gt;% mutate(Estado = "Tocantins")</pre>



<p>O que foi feito aqui é bem simples: eu gerei um&nbsp;<em>dataset&nbsp;</em>dos decretos em cada estado, usando como fonte o link do site. Também foi criado uma coluna com o nome do respectivo estado. O que precisa ser feito agora? Ponto para quem disse unir tudo isso.</p>



<pre class="wp-block-preformatted">####################################################<br>######## Dataset com todos os decretos, por Estado<br>####################################################DECRETOS_ESTADOS &lt;- list(Acre,Alagoas,Amapá,Amazonas,<br>                         Bahia,Ceará,Distrito_Federal,<br>                         Espírito_Santo,Goiás,<br>                         Maranhão,Mato_Grosso,Mato_Grosso_do_Sul,<br>                         Minas_Gerais,Pará,Paraíba,<br>                         Paraná, Pernambuco, Piauí,<br>                         Rio_de_Janeiro,Rio_Grande_do_Norte,<br>                         Rio_Grande_do_Sul,Rondônia,Roraima,<br>                         Santa_Catarina,São_Paulo,<br>                         Sergipe,Tocantins) %&gt;%<br>                  reduce(full_join, by = c("X.U.FEFF.Epigrafe",<br>                                           "Localidade","Ementa",<br>                                           "Url","Estado")) %&gt;%<br>                    rename(Decretos = "X.U.FEFF.Epigrafe")</pre>



<p>E prontinho! Agora temos um banco de dados com todos os estados. Observem que utilizei a função&nbsp;<em>reduce.&nbsp;</em>Ela é do pacote<em>&nbsp;purrr&nbsp;</em>e ajuda na hora de unir todos os bancos, para que não seja necessário unir de dois em dois, com o&nbsp;<em>reduce&nbsp;</em>eu faço a união de todos simultaneamente. A união (ou merge) em si é feita com a função&nbsp;<em>full_join&nbsp;</em>do&nbsp;<em>dplyr,&nbsp;</em>nela eu informo as colunas em comum que serão usadas como base para agregar os dados. Depois eu renomeei o nome de uma coluna para um nome mais agradável (cá entre nós, “X.U.FEFF.Epigrafe” não é um bom nome para uma coluna).</p>



<p>Nossa base de dados tem essa cara por enquanto:</p>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://miro.medium.com/max/976/1*8yZxKOhc8uQulWYuNEaMMg.png" alt="Image for post" width="763" height="463"/></figure>



<p>Agora nos precisamos saber se o decreto é municipal ou estadual. Para isso, basta criar uma coluna e aplicar um&nbsp;<em>ifelse</em>&nbsp;usando a ‘localidade’ como informação. Vejam:</p>



<pre class="wp-block-preformatted">### Criando coluna 'Tipo' com informação se o decreto é Estadual ou MunicipalDECRETOS_ESTADOS &lt;- DECRETOS_ESTADOS %&gt;% mutate(Tipo="")DECRETOS_ESTADOS$Tipo &lt;- ifelse(DECRETOS_ESTADOS$Localidade %in%   c("Acre","Alagoas","Amapá","Amazonas",<br>  "Bahia","Ceará","Distrito Federal",<br>  "Espírito Santo","Goiás","Maranhão",<br>  "Mato Grosso","Mato Grosso do Sul",<br>  "Minas Gerais","Pará","Paraíba","Paraná",<br>  "Pernambuco","Piauí","Rio de Janeiro",<br>  "Rio Grande do Norte","Rio Grande do Sul",<br>  "Rondônia","Roraima","Santa Catarina",<br>  "São Paulo","Sergipe","Tocantins"), "Estadual", "Municipal")</pre>



<p>Agora é necessário incluir os decretos federais. É legal ter um pouco de noção em&nbsp;<em>webscrapping</em>&nbsp;e&nbsp;<em>html</em>. Vamos ver.</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="456c">Incluindo os Decretos Federais</h1>



<p>O site do Governo Federal para obter as informações sobre a legislação sobre o COVID-19 é&nbsp;<a href="http://www.planalto.gov.br/ccivil_03/Portaria/quadro_portaria.htm">esse</a>. Se você acessar o site vai notar que ele tem uma interface bem simples, mas não tem nele uma opção de baixar os dados, por isso, precisamos “raspar” as informações que queremos diretamente da página. O R oferece uma gama de opções para raspar informações de páginas da web, o R Selenium é a mais popular, mas aqui optei por usar o&nbsp;<a href="https://en.wikipedia.org/wiki/PhantomJS">PhantomJs</a>.</p>



<p>Faça o download do PhantomJs acessando a página deles, que é&nbsp;<a href="https://phantomjs.org/download.html">essa aqui</a>. Feito o download e depois de descompactar, coloque o arquivo&nbsp;<em>phantomjs.exe&nbsp;</em>na pasta de trabalho que você definiu (a minha, por exemplo, é&nbsp;<em>“C:\\Users\\pc\\Desktop\\Cidacs\\ETL”</em>), basta olhar o primeiro script, no começo do texto, caso não se recorde.</p>



<p>Certo, com o arquivo na pasta, vamos voltar para o R.</p>



<pre class="wp-block-preformatted">###################################################################<br>###### Decretos Federais - Capturando página e gerando ela em HTML <br>###################################################################writeLines("var url = '<a href="http://www.planalto.gov.br/ccivil_03/Portaria/quadro_portaria.htm'">http://www.planalto.gov.br/ccivil_03/Portaria/quadro_portaria.htm'</a>;<br>var page = new WebPage();<br>var fs = require('fs');page.open(url, function (status) {<br>        just_wait();<br>});function just_wait() {<br>    setTimeout(function() {<br>               fs.write('dec_federal.html', page.content, 'w');<br>            phantom.exit();<br>    }, 2500);<br>}<br>", con = "scrape.js")js_scrape &lt;- function(url = "<a href="http://www.planalto.gov.br/ccivil_03/Portaria/quadro_portaria.htm">http://www.planalto.gov.br/ccivil_03/Portaria/quadro_portaria.htm</a>", <br>                      js_path = "scrape.js", <br>                      phantompath = "phantomjs.exe"){<br>  <br>  lines &lt;- readLines(js_path)<br>  lines[1] &lt;- paste0("var url ='", url ,"';")<br>  writeLines(lines, js_path)<br>  <br>  command = paste(phantompath, js_path, sep = " ")<br>  system(command)<br>  <br>}js_scrape()###################################################################<br>######### Carregando o HTML convertido<br>################################################################### lendo o html<br>html2 &lt;- read_html("dec_federal.html", encoding="UTF-8")# criando formato de tabela com dados do html<br>html_tabela &lt;- html2 %&gt;% html_nodes("table") %&gt;% html_table(fill = T)fed_covid &lt;- html_tabela[[3]]# Ajustando nome das colunas<br>fed_covid &lt;- fed_covid %&gt;% rename(Decretos = "X1") %&gt;% rename(Ementa = "X2")# Ajustando dados no dataset (Excesso de espaçamento, etc)<br>fed_covid$Decretos &lt;- gsub("[\t\n]", "", fed_covid$Decretos)<br>fed_covid$Ementa &lt;- gsub("[\t\n]", "", fed_covid$Ementa)fed_covid$Decretos &lt;- gsub("\\s+"," ", fed_covid$Decretos)<br>fed_covid$Ementa &lt;- gsub("\\s+"," ", fed_covid$Ementa)# Criando coluna 'Tipo' e 'Localidade'<br>fed_covid &lt;- fed_covid %&gt;% mutate(Tipo="Federal") %&gt;% mutate(Localidade="Brasil")</pre>



<p>Na primeira parte do código, o PhantomJs pelo R é usado para acessar a página do planalto e gerar um arquivo em html. Usando esse arquivo em html, na segunda parte do código, foi utilizada algumas funções do pacote&nbsp;<em>rvest&nbsp;</em>para pegar as informações em html e transformá-la em uma tabela. Após isso, foi necessário aplicar alguns processos de limpeza e ajuste nos dados: renomear colunas, usar um pouco de conhecimento em regex para retirar espaçamento em excesso e por fim criar uma coluna ‘Tipo’ e ‘Localidade’.</p>



<p>Essa é a cara do nosso dataset de decretos federais:</p>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/733/1*NpDhsDRcVj-WSk1Wy26uKw.png" alt="Image for post"/></figure>



<p>O próximo passo é fazer um merge entre os decretos federais e o restante.</p>



<pre class="wp-block-preformatted">##################################################################<br>######## Dataset unindo decretos Federais, Estaduais e Municipais<br>##################################################################Decretos_Covid_Brasil &lt;- full_join(DECRETOS_ESTADOS, fed_covid, by=c("Decretos","Localidade","Ementa","Tipo"))</pre>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="7fa5">Criando coluna ‘Tipo do documento’ e limpando os dados</h1>



<p>Para saber se o documento é uma Lei, Decreto ou Portaria é preciso usar a função&nbsp;<em>word</em>&nbsp;do pacote&nbsp;<em>stringr</em>. Essa função pega a primeira palavra de cada linha de determinada coluna, no caso, a coluna ‘Decretos’. Também, por questão de limpeza nos dados, é bom deixar o nome do município, na coluna ‘Localidade’, sem nenhum tipo de ‘/’ ou algo que atrapalhe na busca pelo seu nome.</p>



<pre class="wp-block-preformatted">#### Criando coluna 'Tipo do Documento'Decretos_Covid_Brasil$Tipo_Documento &lt;- word(Decretos_Covid_Brasil$Decretos)### Retirando '/' depois do nome do município <br>Decretos_Covid_Brasil$Localidade &lt;- gsub("\\/.*","",Decretos_Covid_Brasil$Localidade)### Removendo coluna não utilizada<br>Decretos_Covid_Brasil$Url &lt;- NULL</pre>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="8db3">Inserindo o código dos municípios</h1>



<p>Para ajudar na hora de buscar por um determinado município, é sempre melhor usar o código dele do que o nome. Isso porque muitas vezes ocorrem erros de digitação, problemas com acentuação, entre outros. Por isso, é prudente acrescentar uma coluna com o código dos municípios.</p>



<p>Como a coluna que contém o nome dos municípios também tem o nome dos estados, é necessário criar uma condição para que apenas municípios sejam registrados (Para não ter problema, por exemplo, com estados que também tem nome de municípios, como SP ou RJ).</p>



<pre class="wp-block-preformatted">############################################################################## Carregando dataset com códigos dos municípios<br>####################################################################codigos_igbe &lt;- read.csv2("<a href="https://raw.githubusercontent.com/CleitonOERocha/Scripts/master/Decretos%20Covid/codigo_municipios_IBGE.csv">https://raw.githubusercontent.com/CleitonOERocha/Scripts/master/Decretos%20Covid/codigo_municipios_IBGE.csv</a>",<br>                          encoding = "ISO-8859-1", stringsAsFactors = F)### Merge entre códigos e dataset<br>Decretos_Covid_Brasil &lt;- left_join(Decretos_Covid_Brasil, codigos_igbe, by = c("Localidade","Estado"))### Criando condições para registrar apenas Municípios, e não Estados <br>  Decretos_Covid_Brasil$Codigo_Municipio &lt;- ifelse(Decretos_Covid_Brasil$Tipo == "Municipal",<br>                                                  Decretos_Covid_Brasil$Codigo_Municipio, NA)<br>  <br>  Decretos_Covid_Brasil$Nome_Mesorregião &lt;- ifelse(Decretos_Covid_Brasil$Tipo == "Municipal",<br>                                                   Decretos_Covid_Brasil$Nome_Mesorregião, NA)<br>  <br>  Decretos_Covid_Brasil$Cod_UF &lt;- ifelse(Decretos_Covid_Brasil$Tipo == "Municipal",<br>                                         Decretos_Covid_Brasil$Cod_UF, NA)</pre>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="df65">Inserindo a data do decreto e gerando o banco de dados final</h1>



<p>É importante ver a data em que cada decreto foi publicado, tanto para traçar uma linha do tempo, como também para olhar o volume de decretos mês a mês. Para criar a coluna contendo a data é preciso de três pacotes:<em>&nbsp;lubridate</em>,&nbsp;<em>mgsub&nbsp;</em>e&nbsp;<em>gsubfn</em>. Depois de mostrar o script, explico melhor sobre o uso de cada um.</p>



<pre class="wp-block-preformatted">############################################################################# Criando coluna com data dos decretos <br>####################################################################<br>  <br>### criando lista com nome dos meses em português e seu respectivo número <br>  meses_pt &lt;- c("de janeiro de", "de fevereiro de",<br>                "de março de", "de abril de", "de maio de",<br>                "de junho de","de julho de", "de agosto de",<br>                "de setembro de", "de outubro de",<br>                "de novembro de", "de dezembro de")meses_numb &lt;- c("/01/", "/02/", "/03/", "/04/", "/05/", "/06/", "/07/", "/08/", "/09/", "/10/", "/11/", "/12/")### condição para filtrar data na coluna - criando coluna mês<br>  Decretos_Covid_Brasil$Decretos_date &lt;- ifelse(Decretos_Covid_Brasil$Tipo %in% c("Estadual","Municipal"), <br>         mgsub::mgsub(Decretos_Covid_Brasil$Decretos, meses_pt, meses_numb),<br>         strapplyc(Decretos_Covid_Brasil$Decretos, ", de \\d+.\\d+.\\d+", simplify = TRUE))<br>  <br>### Transformando lista em carácter<br>  Decretos_Covid_Brasil$Decretos_date &lt;- as.character(Decretos_Covid_Brasil$Decretos_date)### Criando condição para extrair datas de acordo com seu padrão<br>  Decretos_Covid_Brasil$Decretos_date &lt;- ifelse(Decretos_Covid_Brasil$Tipo %in% c("Estadual","Municipal"),<br>                                              strapplyc(Decretos_Covid_Brasil$Decretos_date, "\\d+ /\\d+/ \\d+", simplify = TRUE), <br>                                               Decretos_Covid_Brasil$Decretos_date)### Convertendo coluna para formato 'Date'<br>  Decretos_Covid_Brasil$Decretos_date &lt;- dmy(Decretos_Covid_Brasil$Decretos_date)</pre>



<p>Vamos a explicação:</p>



<p>Os decretos municipais e estaduais tem um padrão: primeiro vem o dia em formato numérico, depois o mês por extenso, seguido pelo ano em formato numérico. Já os decretos federais vem em formato numérico separados por “.”. É preciso, portanto, elaborar duas formas de extrair as datas.</p>



<p>Para os decretos municipais e estaduais: criei duas listas, a primeira com o formato que a data vem no dataset e uma outra com o formato que eu quero que os dados apareceram (/xx/). Ou seja, pretendo aqui fazer uma substituição dos caracteres para um formato de data mais conciso. Para fazer a substituição, foi utilizado a função&nbsp;<em>mgsub&nbsp;</em>do pacote de mesmo nome.</p>



<p>Para os decretos federais: Como não é necessário fazer nenhuma substituição, apenas o recorte da informação, a função&nbsp;<em>strapplyc&nbsp;</em>do pacote&nbsp;<em>gsubfn&nbsp;</em>foi utilizada. Com ela eu consigo recortar a cadeira de caracteres que desejo.</p>



<p>Com essas duas informações em mãos, foi preciso apenas fazer uma condição usando o&nbsp;<em>ifelse</em>. Mas acaba por ai? Nãaaao.</p>



<p>Depois de fazer criar esse&nbsp;<em>if&nbsp;</em>é preciso converter a coluna criada em carácter. Isso porque depois de usar a função&nbsp;<em>strapplyc</em>,o resultado é uma coluna no formato lista. Essa conversão é necessária porque é preciso criar mais uma condição. Explico:</p>



<p>Na primeira condição, apenas houve uma substituição nos valores dos decretos municipais e estaduais. É preciso, como foi feito nos decretos federais, recortar os dados desejados usando a função&nbsp;<em>strapplyc&nbsp;</em>e como não é preciso fazer mais nada com os decretos federais, apenas repete-se o nome da coluna na condição.</p>



<p>Agora que todos os dados estão recortados, contendo apenas a data, é preciso converter essa coluna para o formato correto dela, ou seja,&nbsp;<em>“Date”&nbsp;</em>(que não é de encontro, rsrs). Para isso, bastar usar a função super simples do pacote lubridate, a&nbsp;<em>dmy</em>, que os dados são automaticamente padronizados.</p>



<p>Este é o nosso banco de dados final:</p>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://miro.medium.com/max/1255/1*oi17URjs9Oy7cTH9zMzMlw.png" alt="Image for post" width="778" height="361"/><figcaption>24.057 decretos. 24.057!!!</figcaption></figure>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="bec6">Salvando</h1>



<p>Só é preciso agora salvar. Vou salvar do seguinte modo: apenas Salvador, todos da Bahia (estaduais e municipais), Bahia (apenas estaduais), Federais e a base de dados completa, ou seja, para o Brasil todo.</p>



<pre class="wp-block-preformatted">############################################################<br>############# Dataset com todos os decretos em Salvador<br>############################################################DECRETOS_SALVADOR &lt;- Decretos_Covid_Brasil %&gt;% filter(Localidade == "Salvador")####################################################################### Dataset com todos os decretos na Bahia - Apenas Estaduais e Estaduais/Municipais ######################################################DECRETOS_BAHIA_ESTADUAL &lt;- Decretos_Covid_Brasil %&gt;% filter(Localidade == "Bahia") %&gt;% <br>                           select(Localidade, Decretos, Ementa, Tipo, Tipo_Documento) # Decretos EstaduaisDECRETOS_BAHIA_TODOS &lt;- Decretos_Covid_Brasil %&gt;% filter(Estado == "Bahia") # Decretos do Estado e Municipios#############################################<br>######## Dataset com decretos Federais<br>#############################################DECRETOS_FEDERAIS &lt;- Decretos_Covid_Brasil %&gt;% filter(Localidade == "Brasil") %&gt;% select(Localidade, Decretos, Ementa, Tipo, Tipo_Documento)###########################################################<br>########## Salvando em CSV<br>###########################################################write.csv2(DECRETOS_SALVADOR,"Decretos_em_Salvador.csv", row.names = F) # SSA<br>write.csv2(DECRETOS_BAHIA_ESTADUAL,"DecretosEstaduais_na_Bahia.csv", row.names = F) # BA Estadual<br>write.csv2(DECRETOS_BAHIA_TODOS,"Decretos_na_Bahia.csv", row.names = F) # Ba Estaduais e Municipais<br>write.csv2(Decretos_Covid_Brasil,"Decretos_Covid_Brasil.csv", row.names = F) # Todos os decretos no Brasil<br>write.csv2(DECRETOS_FEDERAIS,"Decretos_Federais.csv", row.names = F) # Federais</pre>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="ba47">Conclusão</h1>



<p>O script completo está aqui no meu&nbsp;<a href="https://github.com/CleitonOERocha/Scripts/blob/master/Decretos%20Covid/ETL_decretos.R">GitHub</a>. Usem! Porém, levou um tempo considerável para elaborar, solucionar erros e ir aprimorando o script, então, se gostou do conteúdo e ele foi realmente útil, por favor, lembre-se de dar os créditos. Isso ajuda pra caramba <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2764.png" alt="❤" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</p>



<p>Aqui estão minhas redes sociais:&nbsp;<a href="https://www.instagram.com/cleiton._r/">Instagram</a>,&nbsp;<a href="https://www.linkedin.com/in/cleitonoerocha/">LinkedIn</a>,&nbsp;<a href="https://github.com/CleitonOERocha">GitHub</a>.</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="2b36">Bônus</h1>



<p>Não poderia encerrar sem construir uns gráficos, hahaha.</p>



<pre class="wp-block-preformatted">library(viridis)<br>library(dplyr)<br>library(ggplot2)<br>library(Cairo)<br>library(tidyr)<br>library(ggrepel)# Pasta de trabalho<br>setwd("C:\\Users\\pc\\Desktop\\Cidacs\\ETL")# Dados<br>Decretos_Covid_Brasil &lt;- read.csv2("Decretos_Covid_Brasil.csv")Decretos_Covid_Brasil &lt;- Decretos_Covid_Brasil %&gt;% mutate(one=1)</pre>



<p><strong>Decretos, por mês:</strong></p>



<pre class="wp-block-preformatted">######################## Gráficos - Decretos por mês ################################# Recortando apenas o mês do decreto<br>Decretos_Covid_Brasil$mes_dec &lt;- format(as.Date(Decretos_Covid_Brasil$Decretos_date), "%m")# Nome do mês<br>Decretos_Covid_Brasil$mes_dec &lt;- factor(Decretos_Covid_Brasil$mes_dec, levels = c("01","02","03","04",<br>                                                                                  "05","06","07","08","09"),<br>                                        labels = c("Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho",<br>                                                   "Agosto","Setembro"))# Agrupando<br>total_mes &lt;- Decretos_Covid_Brasil %&gt;% <br>  group_by(mes_dec) %&gt;% <br>  summarise(total=sum(one)) %&gt;% <br>  drop_na()# gráfico<br>graph_mes &lt;- ggplot(total_mes, aes(fill = mes_dec, y = total, x =mes_dec)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=total),size = 2.5, position =position_dodge(width=0.9),<br>             vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=8),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "none") +<br>  labs(x = "", y="", caption = "Fonte: <a href="https://leismunicipais.com.br//nDados">https://leismunicipais.com.br/\nDados</a> coletados em 08/09/2020",<br>       title = "Total de decretos no Brasil, por mês") +<br>  scale_fill_viridis(discrete=TRUE,option = "B") +<br>  scale_y_discrete(limits=factor(0:6000), breaks = c(0,1000,2000,3000,4000,5000,6000), name = "")# Salvando em PNG<br>ggsave(plot = graph_mes, "graph_mes.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://miro.medium.com/max/1080/1*G4Uq_K7LwNLFydSXCteJ3A.png" alt="Image for post" width="674" height="338"/></figure>



<p><strong>Por ato normativo:</strong></p>



<pre class="wp-block-preformatted">######################## Tipo de ato normativo #################### Agrupando <br>total_doc &lt;- Decretos_Covid_Brasil %&gt;% <br>  group_by(Tipo_Documento) %&gt;% <br>  summarise(total=sum(one)) %&gt;% <br>  drop_na()# Classificando decretos menores que 100 em 'Outros'<br>total_doc$Tipo_Documento &lt;- ifelse(total_doc$total &lt; 100,"Outros",<br>                                   total_doc$Tipo_Documento)# reagrupando e calculando porcentagem <br>total_doc &lt;- total_doc %&gt;% <br>  group_by(Tipo_Documento) %&gt;% <br>  summarise(total=sum(total)) %&gt;% <br>  drop_na() %&gt;% <br>  mutate(percent = total/sum(total)*100)# criando coluna com a posicao da legenda<br>total_doc &lt;- total_doc %&gt;% arrange(desc(Tipo_Documento)) %&gt;%<br>  mutate(yposicao_legenda = cumsum(percent)- 0.5*percent)# gráfico<br>ato_graph &lt;- ggplot(total_doc,aes(x= "", y= percent, fill=Tipo_Documento)) +<br>  geom_bar(width=1, stat = "identity") +<br>  coord_polar("y", start=0) +<br>   geom_label_repel(aes(y=yposicao_legenda, label = sprintf("%1.1f%%",percent)), size = 4,<br>                         color = 'black',fontface='bold') +<br>  labs(x="",y="",title = "Tipo de ato normativo", fill = "Ato normativo: ",<br>       caption = "Fonte: <a href="https://leismunicipais.com.br//nDados">https://leismunicipais.com.br/\nDados</a> coletados em 08/09/2020") +<br>  theme_minimal() +<br>  theme(legend.position="bottom",<br>        legend.background = element_rect(fill="ghostwhite", size=0.5, linetype="blank"),<br>        axis.text.x = element_text(face="bold",color="#000000", size=12),<br>        legend.text = element_text(size=10, face="bold"),<br>        legend.title = element_text(size = 8, face = "bold"),<br>        plot.title = element_text(colour = "black", size = 12, hjust=0.5, face="bold")) +<br>  scale_fill_manual(values = c("#581845","#900C3F","#C70039","#FF5733","#FFC300"))# Salvando em PNG<br>ggsave(plot = ato_graph, "ato_graph.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://miro.medium.com/max/1080/1*f1Wc_y7noNp9ThFjbB1RrA.png" alt="Image for post" width="801" height="402"/></figure>



<p>O script dos gráficos vocês encontram&nbsp;<a href="https://github.com/CleitonOERocha/Scripts/blob/master/Decretos%20Covid/graf_medium.R">aqui.</a></p>



<p>#R #datascience #Rstats</p>



<p></p>
<p>O post <a href="http://estatidados.com.br/utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil/">Utilizando o R para obter decretos relacionados ao COVID-19 no Brasil</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/utilizando-o-r-para-obter-decretos-relacionados-ao-covid-19-no-brasil/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Trabalhando com os microdados da PNAD COVID19 no R</title>
		<link>http://estatidados.com.br/trabalhando-com-os-microdados-da-pnad-covid19-no-r/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=trabalhando-com-os-microdados-da-pnad-covid19-no-r</link>
					<comments>http://estatidados.com.br/trabalhando-com-os-microdados-da-pnad-covid19-no-r/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 29 Sep 2020 15:41:01 +0000</pubDate>
				<category><![CDATA[Cleiton Rocha]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=438</guid>

					<description><![CDATA[<p>Edit:&#160;Quando fiz esse texto, os dados da PNAD Covid-19 mais recentes foram de Maio. Recentemente, o IBGE publicou dados mais atualizados, com o mês de Junho. Por isso, estou atualizando os gráficos com os novos dados, para além disso, fiz<a class="leiamais" href="http://estatidados.com.br/trabalhando-com-os-microdados-da-pnad-covid19-no-r/" title="Trabalhando com os microdados da PNAD COVID19 no R">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/trabalhando-com-os-microdados-da-pnad-covid19-no-r/">Trabalhando com os microdados da PNAD COVID19 no R</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="576" height="302" src="http://estatidados.com.br/wp-content/uploads/2020/09/1_0ZYQcZAF0kv7axu9yUx9EA.png" alt="" class="wp-image-439" srcset="http://estatidados.com.br/wp-content/uploads/2020/09/1_0ZYQcZAF0kv7axu9yUx9EA.png 576w, http://estatidados.com.br/wp-content/uploads/2020/09/1_0ZYQcZAF0kv7axu9yUx9EA-300x157.png 300w, http://estatidados.com.br/wp-content/uploads/2020/09/1_0ZYQcZAF0kv7axu9yUx9EA-200x105.png 200w, http://estatidados.com.br/wp-content/uploads/2020/09/1_0ZYQcZAF0kv7axu9yUx9EA-400x210.png 400w" sizes="auto, (max-width: 576px) 100vw, 576px" /></figure>



<p><strong>Edit:</strong>&nbsp;Quando fiz esse texto, os dados da PNAD Covid-19 mais recentes foram de Maio. Recentemente, o IBGE publicou dados mais atualizados, com o mês de Junho. Por isso, estou atualizando os gráficos com os novos dados, para além disso, fiz alguns ajustes no script.</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="3bca">Introdução</h1>



<p>Os microdados da PNAD são, na minha opinião, uma das formas mais preciosas para compreender as condições socioeconômicas e demográficas do Brasil. Trata-se de uma base com ampla capilaridade e milhões de linhas repleta de informações da população brasileira. O indivíduo trabalha? Qual o valor da remuneração? Estudou até quando? Sabe ler? Como são as condições na sua residência? Nela tem água tratada? Esgoto? São questões abordadas na PNAD Continua e que servem de base para desenvolver e analisar políticas públicas diversas.</p>



<p>Em um período de pandemia, cuja solução momentânea que se mostra mais eficiente é o isolamento social, levar pesquisadores à campo para aplicar questionários da maneira habitual se mostrou uma tarefa pouco adequada. Pensando nisso e para manter a sociedade informada, o IBGE buscou contornar a situação via entrevistas realizadas por telefone. Com as informações coletadas foi gerada a PNAD COVID19. O IBGE frisa que os&nbsp;<a href="https://www.ibge.gov.br/estatisticas/investigacoes-experimentais/estatisticas-experimentais/27946-divulgacao-semanal-pnadcovid1?t=o-que-e&amp;utm_source=covid19&amp;utm_medium=hotsite&amp;utm_campaign=covid_19">dados são experimentais</a>&nbsp;e devem ser usadas com cautela, isso porque essa é uma PNAD diferente das outras, ou seja, é arriscado comparar os dados dessa PNAD com a PNADC de 2019, por exemplo. Todavia, isso não quer dizer que a informação seja inválida, longe disso, na verdade, ela fornece um olhar para o período atípico que nos encontramos.</p>



<p>Dentro do R existe uma gama de opções para analisar amostras, geralmente o pacote&nbsp;<em>Survey</em>&nbsp;é o predileto dos pesquisadores. Porém, optei pelo&nbsp;<em>srvyr</em>, por ser um pacote que fornece opções para trabalhar com o&nbsp;<em>dplyr</em>. Foquei em analisar o que se passa em Salvador, mas é possível reproduzir os resultados para outras capitais, UF’s ou simplesmente para o Brasil todo, a curiosidade de cada um é o que faz com que tenhamos novas descobertas e inovações.</p>



<p>Então, depois de toda essa explicação, vamos ao que é mais legal: botar a mão na massa!</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="9dbc">Carregando pacotes e os microdados</h1>



<p>Primeira coisa: faça o download dos&nbsp;<a href="https://www.ibge.gov.br/estatisticas/investigacoes-experimentais/estatisticas-experimentais/27946-divulgacao-semanal-pnadcovid1?t=microdados&amp;utm_source=covid19&amp;utm_medium=hotsite&amp;utm_campaign=covid_19">microdados no site do IBGE</a>. Depois de descompactar, verá que existe um arquivo CSV (que são os dados) e o dicionário. Tudo bem usual pra quem já trabalhou com PNAD antes.</p>



<p>Com os dados no computador, vamos instalar os pacotes e carregar os dados no RStudio.</p>



<pre class="wp-block-preformatted">library(dplyr)<br>library(srvyr) <br>library(readr)<br>library(ggplot2)<br>library(Cairo)# Pasta de Trabalho<br>setwd("C:\\Users\\pc\\Desktop\\PNAD\\PNAD_COVID19\\PNAD_COVID_062020")# Carregando dataset<br>pnad_covid &lt;- read_csv("PNAD_COVID_062020.csv", col_types = cols(.default = "d"))</pre>



<p>O dataset completo tem 381.270 linhas e 114 colunas (woooow).</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="ecce">Colocando os pesos e criando variáveis</h1>



<p>Se você abrir o dicionário da PNAD COVID19 vai notar uma variável chamada V1032. É essa variável que define o peso do domicílio e das pessoas. Precisamos ligar isso no nosso dataset. Também vou filtrar a capital para Salvador.</p>



<pre class="wp-block-preformatted"># ligando Pesos e filtrando Salvador<br>pnad_com_pesos &lt;- pnad_covid %&gt;% as_survey_design(ids = UPA, strata = Estrato, weights = V1032, nest = TRUE) %&gt;%<br>  filter(CAPITAL == "29")</pre>



<p>Agora vamos criar algumas colunas com as informações que queremos trabalhar.</p>



<pre class="wp-block-preformatted"># Criando colunas com Variáveis <br>pnad_com_pesos &lt;- pnad_com_pesos %&gt;% mutate(one = 1,<br>Sexo = ifelse(A003 == 1, "Homem", "Mulher"), <br>Idade = case_when(<br>   A002 %in% 15:24 ~ "15-24",<br>   A002 %in% 25:34 ~ "25-34", <br>   A002 %in% 35:49 ~ "35-49", <br>   A002 %in% 50:64 ~ "50-64", <br>   A002 &gt; 64 ~ "65+"),<br>Cor = case_when(<br>   A004 == 1 ~ "Branca", <br>   A004 == 2 ~ "Preta", <br>   A004 == 4 ~ "Parda"),<br>Escolaridade = factor(case_when( <br>   A005 %in% 1:2 ~ "Sem Instrução ou Fundamental Incompleto", <br>   A005 %in% 3:4 ~ "Fundamental completo ou Médio Incompleto", <br>   A005 %in% 5:6 ~ "Médio completo ou Superior Incompleto", <br>   A005 == 7 ~ "Superior completo", <br>   A005 == 8 ~ "Pós-graduação"), <br>     levels = c( "Sem Instrução ou Fundamental Incompleto",<br>                 "Fundamental completo ou Médio Incompleto", <br>                 "Médio completo ou Superior Incompleto",<br>                 "Superior completo",<br>                 "Pós-graduação")), <br>Tipo_emprego = factor(case_when(<br>   C007 == 1 ~ "Trabalhador doméstico (empregado doméstico, cuidados, babá)",<br>   C007 == 2 ~ "Militar",<br>   C007 == 3 ~ "Policial ou Bombeiro",<br>   C007 == 4 ~ "Setor privado",<br>   C007 == 5 ~ "Setor público",<br>   C007 == 6 ~ "Empregador",<br>   C007 == 7 ~ "Autônomo (Conta própria)"),<br>     levels = c( "Trabalhador doméstico (empregado doméstico, cuidados, babá)",<br>               "Militar", <br>               "Policial ou Bombeiro",<br>               "Setor privado",<br>               "Setor público",<br>               "Empregador",<br>               "Autônomo (Conta própria)")), <br>Faixa_salario = factor(case_when(<br>  C01012 &lt;= 1044 ~ "Menos de um salário mínimo",<br>  C01012 %in% c(1045:2090) ~ "Entre 1 e 2",<br>  C01012 %in% c(2091:3135) ~ "Entre 2 e 3",<br>  C01012 %in% c(3136:4180) ~ "Entre 3 e 4",<br>  C01012 %in% c(4181:5225) ~ "Entre 4 e 5",<br>  C01012 &gt;= 5226 ~ "Mais de 5"),<br>    levels = c("Menos de um salário mínimo",<br>               "Entre 1 e 2",<br>               "Entre 2 e 3",<br>               "Entre 3 e 4",<br>               "Entre 4 e 5",<br>               "Mais de 5")),<br>domicilio_situacao = factor(case_when(<br>  F001 == 1 ~ "Próprio - já pago",<br>  F001 == 2 ~ "Próprio - ainda pagando" ,                                  <br>  F001 == 3 ~ "Alugado",<br>  F001 %in% 4:6 ~ "Cedido (Por empregador, Familiar ou outro)"),<br>      levels = c("Próprio - já pago",<br>                 "Próprio - ainda pagando",<br>                 "Alugado", <br>                 "Cedido (Por empregador, Familiar ou outro)")),<br>home_office = ifelse(C013 == 1, "Home Office", "Presencial"),<br>auxilio_emergencial = ifelse(D0051 == 1, "Auxílio", "Sem auxílio")<br>)</pre>



<p>Ficaria um texto muuuuito longo se eu fosse detalhar cada etapa, mas em resumo: Foram criadas novas colunas e nelas eu apliquei um rótulo baseado nas colunas que já existem, ou seja, ao invés de uma coluna chamada A003, contendo apenas os valores 1 e 2, eu criei uma nova coluna chamada “Sexo” com as informações “Homem” e “Mulher”, assim fica mais fácil de interpretar. Para fazer sua análise, confira o dicionário que veio junto com os dados (O dicionário é muito importante, não se esqueça dele).</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="4ad0"><strong>Gerando gráficos e analisando resultados</strong></h1>



<p>Um ponto importante sobre os gráficos a seguir: Cada percentual é referente ao total daquele grupo, não tendo uma relação com o percentual ao lado. Por exemplo, quando eu digo que 31,91% das mulheres de cor branca estão em home office, isso significa que 68,09% das mulheres de cor branca não estão em home office. Ou seja, cada grupo tem seu percentual próprio. Optei por fazer isso por achar mais interessante comparar cada grupo com o total dele na sociedade. Maaas, caso queiram trabalhar com gráficos em que a soma dos percentuais atinjam 100%, fiz um outro script que está disponível&nbsp;<a href="https://github.com/CleitonOERocha/Scripts/blob/master/PNAD_COVID19/PNAD_COVID_SSA_100%25.R">aqui</a>. Lá no git também tem uma pasta com os gráficos desse outro script, você poderá encontrar&nbsp;<a href="https://github.com/CleitonOERocha/Scripts/tree/master/PNAD_COVID19/Salvador%20100%25">aqui</a>. Dito tudo isso, vamos partir para as análises!</p>



<p>Primeiro vamos olhar o sexo e a cor das pessoas que estão em Home Office em Salvador.</p>



<pre class="wp-block-preformatted">############### Home office - Por sexo e cor ################### Criando dataset para conferir pessoas em Home Office<br>home_sexo_cor &lt;- pnad_com_pesos %&gt;%<br>  group_by(Sexo, Cor) %&gt;%<br>  summarise(<br>    home_office = survey_total(C013 == 1, na.rm = TRUE),<br>    mao_de_obra = survey_total(C001 == 1, na.rm = TRUE)) %&gt;%<br>  mutate(trab_home_office = (home_office/mao_de_obra)*100) %&gt;%<br>  drop_na()# gráfico<br>home_sexo_cor_ssa &lt;- ggplot(home_sexo_cor, aes(fill = Cor, y = trab_home_office, x = Sexo)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",trab_home_office)),size = 3, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "bottom", legend.background = element_rect(fill="ghostwhite", size=0.7, linetype="blank")) +<br>  labs(x = "Sexo", fill = "Cor/Raça: ", caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas em home office, por cor/raça e sexo - Salvador/BA") +<br>  scale_fill_manual(values = c("#00b894","#ff7675","#0984e3","#6c5ce7")) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando<br>ggsave(plot = home_sexo_cor_ssa, "home_sexo_cor_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*zZ8fBVydaEDoCab7Cj6qeA.png" alt="Image for post"/></figure>



<p>Podemos ver que mulheres de cor branca são o grupo predominante em home office, 31,91% dos indivíduos com essas duas características se encontram trabalhando em casa. Já o menor grupo são o de homens de cor preta, com um singelo percentual de 9,14%.</p>



<p>Mas e quanto ao nível de escolaridade? Como ele se comporta? Vamos observar.</p>



<pre class="wp-block-preformatted">############## Home office - Por Cor e Escolaridade ###########home_edu_cor &lt;- pnad_com_pesos %&gt;%<br>  group_by(Escolaridade, Cor) %&gt;%<br>  summarise(<br>    home_office = survey_total(C013 == 1, na.rm = TRUE),<br>    mao_de_obra = survey_total(C001 == 1, na.rm = TRUE)<br>  ) %&gt;%<br>  mutate(trab_home_office = (home_office/mao_de_obra)*100) %&gt;%<br>  drop_na()# gráfico<br>home_edu_cor_ssa &lt;- ggplot(home_edu_cor, aes(fill = Escolaridade, y = trab_home_office, x = Cor)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",trab_home_office)),size = 3, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "bottom", legend.background = element_rect(fill="ghostwhite", size=0.7, linetype="blank")) +<br>  labs(x = "Cor/Raça", fill = "Escolaridade: ", caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas em home office, por cor/raça e escolaridade - Salvador/BA ") +<br>  scale_fill_manual(values = c("#00b894","#ff7675","#0984e3","#6c5ce7","#fdcb6e")) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = home_edu_cor_ssa, "home_edu_cor_ssa.png",<br>       width = 14, height = 7, dpi = 150, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1890/1*tBsI2DhG3E7SKOoCr4uT-Q.png" alt="Image for post"/></figure>



<p>Podemos ver algumas coisas interessantes com esse gráfico:</p>



<ol class="wp-block-list"><li>Pessoas sem instrução ou com o fundamental incompleto não aparecem em home office ou aparecem com um percentual muito pequeno. Isso pode estar acontecendo pelas condições econômicas dessas pessoas, que não possuem um emprego formal que sustente a condição de fazer um home office ou porque essas pessoas no geral se encontram em algum tipo de trabalho informal. Um outra olhar é de que a pesquisa não conseguiu alcançar essas pessoas, dado que a coleta dos dados ocorreu por meio de entrevista por telefone. Cabe uma análise mais profunda a posteriori.</li><li>Existe um pequeno grupo de pessoas de cor parda e que tem fundamental completo ou médio incompleto que estão em home office. Também existe um pequeno grupo de pessoas de cor preta sem instrução ou com fundamental incompleto que estão em home office.</li><li>O nível de escolaridade é um fator preponderante para estar ou não em home office, isso pode ser notado pela evolução do nível de escolaridade e aumento no percentual de pessoas em home office. Pessoas com pós-graduação tem mais chances de estar trabalhando remotamente do que alguém com apenas o ensino médio.</li></ol>



<p>Vamos ver agora como está a relação Sexo/Idade.</p>



<pre class="wp-block-preformatted">################## Home office - Por Sexo e Idade ################home_sexo_idade &lt;- pnad_com_pesos %&gt;%<br>  group_by(Sexo, Idade) %&gt;%<br>  summarise(<br>    home_office = survey_total(C013 == 1, na.rm = TRUE),<br>    mao_de_obra = survey_total(C001 == 1, na.rm = TRUE)<br>  ) %&gt;%<br>  mutate(trab_home_office = (home_office/mao_de_obra)*100) %&gt;%<br>  drop_na()# gráfico<br>home_sexo_idade_ssa &lt;- ggplot(home_sexo_idade, aes(fill = Idade, y = trab_home_office, x = Sexo)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",trab_home_office)),size = 3, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "bottom", legend.background = element_rect(fill="ghostwhite", size=0.7, linetype="blank")) +<br>  labs(x = "Sexo", fill = "Faixa Etária: ", caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas em home office, por sexo e faixa etária - Salvador/BA") +<br>  scale_fill_manual(values = c("#00b894","#ff7675","#0984e3","#6c5ce7","#fdcb6e")) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = home_sexo_idade_ssa, "home_sexo_idade_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*zUdt-Z12sLqyjfULBqoMKA.png" alt="Image for post"/></figure>



<p>Empiricamente é tentador pensar que quanto maior a idade, maior a chance de estar em home office. Talvez porque imagina-se que pessoas com mais idade tenderiam a ocupar cargos mais altos e que estariam aptas a exercer suas funções em casa. Mas não foi isso que os dados mostraram para Salvador. Os valores são muitos semelhantes em todas as faixas. Com exceção no grupo das mulheres, onde 70,32% daquelas com mais de 65 anos estão em home office.</p>



<p>E quanto ao emprego dessas pessoas? Qual vinculo empregatício mantém mais pessoas trabalhando em casa?</p>



<pre class="wp-block-preformatted">################### Home office - Por trabalho ####################home_emprego &lt;- pnad_com_pesos %&gt;%<br>  group_by(Tipo_emprego) %&gt;%<br>  summarise(<br>    home_office = survey_total(C013 == 1, na.rm = TRUE),<br>    mao_de_obra = survey_total(C001 == 1, na.rm = TRUE)) %&gt;%<br>  mutate(trab_home_office = (home_office/mao_de_obra)*100) %&gt;%<br>  drop_na()# ordenando eixo X<br>legenda_trabalhos &lt;- c("Trabalhador doméstico\n (empregado doméstico,\n cuidados, babá)",<br>"Militar", <br>"Policial ou\n Bombeiro",<br>"Setor privado",<br>"Setor público",<br>"Empregador",<br>"Autônomo\n (Conta própria)")# Gráfico<br>home_emprego_ssa &lt;- ggplot(home_emprego, aes(fill = Tipo_emprego, y = trab_home_office, x = Tipo_emprego)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",trab_home_office)),size = 3, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=8),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "none") +<br>  labs(x = "Tipo de Ocupação",<br>       caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas em home office, por tipo de ocupação - Salvador/BA") +<br>  scale_fill_manual(values = c("#00b894","#ff7675","#0984e3","#6c5ce7","#fdcb6e","#636e72", "#55efc4")) +<br>  scale_x_discrete(labels = legenda_trabalhos) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = home_emprego_ssa, "home_emprego_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*nLpFY3hv-w5M11P6JiWa8Q.png" alt="Image for post"/></figure>



<p>Podemos ver que é no setor público onde mais pessoas estão em home office. Trabalhadores autônomos são os que mais exercem suas atividades fora de casa. Para categorias da segurança pública, militares ou trabalhadores domésticos não foram encontrados resultados na capital baiana.</p>



<p>Como está a distribuição entre cor/raça e salários das pessoas em home office?</p>



<pre class="wp-block-preformatted">############## Home office - Por faixa salarial e cor ##############home_renda &lt;- pnad_com_pesos %&gt;%<br>  group_by(Faixa_salario, Cor) %&gt;%<br>  summarise(<br>    home_office = survey_total(C013 == 1, na.rm = TRUE),<br>    mao_de_obra = survey_total(C001 == 1, na.rm = TRUE)) %&gt;%<br>  mutate(trab_home_office = (home_office / mao_de_obra) * 100) %&gt;%<br>  drop_na()# gráfico<br>home_renda_ssa &lt;- ggplot(home_renda, aes(fill = Faixa_salario, y = trab_home_office, x = Cor)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",trab_home_office)),size = 2.5, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "bottom", legend.background = element_rect(fill="ghostwhite", size=0.7, linetype="blank")) +<br>  labs(x = "Cor/Raça", fill = "Faixa Salarial:\n(Salários mínimos) ", caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas em home office, por cor/raça e faixa salarial - Salvador/BA ") +<br>  scale_fill_manual(values = c("#fad390","#e55039","#4a69bd","#60a3bc","#78e08f","#079992")) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = home_renda_ssa, "home_renda_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*aZ3mFJakirQ1WR79NMJYNg.png" alt="Image for post"/></figure>



<p>Podemos observar um percentual alto de pessoas que recebem 4, 5 ou mais salários mínimos em home office. Mas o mais interesse é ver que entre pessoas brancas que recebem menos de um salário mínimo, 23,20% estão mantendo suas atividades em home office. Olhando o mesmo rendimento para pardos e pretos, o percentual encontrado é bem menor, 12,89% e 9,05% respectivamente.</p>



<p>Mas vamos mudar o foco agora. Deixar de olhar apenas trabalhadores em home office e passar a ver como o auxilio emergencial tem sido direcionado; qual o reflexo desse auxilio na população.</p>



<p>Vamos começar olhando quem recebeu o auxilio.</p>



<pre class="wp-block-preformatted">#################### Auxilio - Sexo e Cor #######################<br>auxilio_cor_sexo &lt;- pnad_com_pesos %&gt;%<br>  group_by(Cor, Sexo) %&gt;%<br>  summarise(<br>    auxilio = survey_total(D0051 == 1, na.rm = TRUE),<br>    total = survey_total(one, na.rm = TRUE)<br>  ) %&gt;%<br>  mutate(pessoas_auxilio = (auxilio/total)*100) %&gt;%<br>  drop_na()# gráfico<br>auxilio_cor_sexo_ssa &lt;- ggplot(auxilio_cor_sexo, aes(fill = Cor, y = pessoas_auxilio, x = Sexo)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",pessoas_auxilio)),size = 3, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "bottom", legend.background = element_rect(fill="ghostwhite", size=0.7, linetype="blank")) +<br>  labs(fill = "Cor: ", x = "Sexo", caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas que receberam auxílio emergencial, por cor/raça e sexo -\n Salvador/BA") +<br>  scale_fill_manual(values = c("#00b894","#ff7675","#0984e3")) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = auxilio_cor_sexo_ssa, "auxilio_cor_sexo_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*D7JBwu3Z44Scq7UUIjRVxg.png" alt="Image for post"/></figure>



<p>Pardos e Pretos são os grupos que mais receberam o auxilio. Entre os gêneros, os valores são muitos próximos. 50,60% dos homens de cor parda receberam o auxilio, já entre as mulheres de mesma cor, 50,90%. Brancos são o menor grupo em ambos os sexos.</p>



<p>E como anda a renda dessas pessoas que receberam o auxílio?</p>



<pre class="wp-block-preformatted">##################### Auxilio - Faixa Salarial ####################auxilio_renda &lt;- pnad_com_pesos %&gt;%<br>  group_by(Faixa_salario) %&gt;%<br>  summarise(<br>    auxilio = survey_total(D0051 == 1, na.rm = TRUE),<br>    total = survey_total(one, na.rm = TRUE)) %&gt;%<br>  mutate(pessoas_auxilio = (auxilio/total)*100) %&gt;%<br>  drop_na()# gráfico<br>auxilio_renda_ssa &lt;- ggplot(auxilio_renda, aes(fill = Faixa_salario, y = pessoas_auxilio, x = Faixa_salario)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",pessoas_auxilio)),size = 3, position =position_dodge(width=0.9),<br>            hjust=-0.1, color = 'black',fontface='bold') +<br>  theme_classic() +<br>  coord_flip() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "none") +<br>  labs(x = "Faixa Salarial", caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Pessoas que receberam auxílio emergencial, por renda - Salvador/BA") +<br>  scale_fill_manual(values = c("#00b894","#ff7675","#0984e3","#6c5ce7","#fdcb6e","#636e72")) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = auxilio_renda_ssa, "auxilio_renda_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*ydjQZ8qPyhOPJmhLvrbdhg.png" alt="Image for post"/></figure>



<p>Nota-se que 73,90% das pessoas que viviam com menos de um salário mínimo receberam o auxílio. Dentre aqueles cuja renda permeiam entre 1 e 2 salários, uma parcela expressiva, 45,39%, recebeu o dinheiro. Uma pequena parcela da população, com renda entre 4 e 5, ou mais de 5 salários mínimos também foram contempladas.</p>



<p>Sabemos que o custo de moradia é algo que pesa no orçamento das famílias, por isso considero interessante ver a situação domiciliar daqueles que estão recebendo o auxilio.</p>



<pre class="wp-block-preformatted">################ Auxilio - Por tipo do domicilio ###################auxilio_domicilio &lt;- pnad_com_pesos %&gt;%<br>  group_by(domicilio_situacao) %&gt;%<br>  summarise(<br>    auxilio = survey_total(D0051 == 1, na.rm = TRUE),<br>    total = survey_total(one, na.rm = TRUE)) %&gt;%<br>  mutate(pessoas_auxilio  = (auxilio/total)*100) %&gt;%<br>  drop_na()# ordenando eixo X<br>legenda_domicilio &lt;- c("Próprio (já pago)",<br>                       "Próprio (ainda pagando)",<br>                       "Alugado", <br>                       "Cedido (Por empregador,\n Familiar ou outro)")# gráfico<br>auxilio_domicilio_ssa &lt;- ggplot(auxilio_domicilio, aes(fill = domicilio_situacao, y = pessoas_auxilio, x = domicilio_situacao)) +<br>  geom_bar(position = "dodge", stat = "identity") +<br>  geom_text(aes(label=sprintf("%1.2f%%",pessoas_auxilio)),size = 3, position =position_dodge(width=0.9),<br>            vjust=-0.5, color = 'black',fontface='bold') +<br>  # geom_text(aes(label=paste0(format(round(auxilio,0),<br>  #                            nsmall=0,big.mark=".", decimal.mark=",")," com auxilio")),<br>  #           size = 3,position = position_stack(vjust = .5),<br>  #           vjust=-0.5, color = 'black',fontface='bold') +<br>  # geom_text(aes(label=paste0(format(round(total,0),<br>  #                                   nsmall=0,big.mark=".", decimal.mark=",")," total")),<br>  #           size = 3,position = position_stack(vjust = .3),<br>  #           vjust=-0.5, color = 'black',fontface='bold') +<br> theme_classic() +<br>  theme(axis.title.x = element_text(colour = "black"),<br>        axis.title.y = element_text(colour = "black"),<br>        axis.text.y = element_text(face="bold", color="#000000", <br>                                   size=10),<br>        axis.line = element_line(colour = "black", <br>                                 size = 1, linetype = "solid"),<br>        axis.text=element_text(size=6, face="bold"),<br>        axis.text.x = element_text(face="bold", color="#000000", size=10),<br>        plot.title = element_text(colour = "black", size = 17, hjust=0.5),<br>        legend.position = "none") +<br>  labs(x = "Tipo de domicílio", y ="Percentual (%)",caption = "Fonte: Microdados da Pnad Covid19 - IBGE. Junho 2020.",<br>       title = "Situação do domicílio daqueles que receberam o auxílio emergencial -\n Salvador/BA") +<br>  scale_fill_manual(values = c("#fad390","#e55039","#4a69bd","#60a3bc","#78e08f","#079992")) +<br>  scale_x_discrete(labels = legenda_domicilio) +<br>  scale_y_discrete(limits=factor(0:100), breaks = c(0,10,20,30,40,50,60,70,80,90,100), name = "Percentual (%)")# Salvando em PNG<br>ggsave(plot = auxilio_domicilio_ssa, "auxilio_domicilio_ssa.png",<br>       width = 10, height = 5, dpi = 120, units = "in",type = "cairo")</pre>



<figure class="wp-block-image"><img decoding="async" src="https://miro.medium.com/max/1080/1*7NmmrXBMXM1wlX4nFefofg.png" alt="Image for post"/></figure>



<p>É interessante ver que 48,56% das pessoas com imóvel próprio receberam o auxilio. 65,65% daqueles que de alguma forma vivem em um imóvel cedido também foram beneficiados. 40,75% dos que pagam aluguel foram contemplados, isso significa que dentre os que pagam aluguel, 59,25% não receberam o pagamento do governo.</p>



<hr class="wp-block-separator"/>



<h1 class="wp-block-heading" id="ec7d">Considerações Finais</h1>



<p>Todo o script você poderá encontrar no meu&nbsp;<a href="https://github.com/CleitonOERocha/Scripts/blob/master/PNAD_COVID19/PNADCOVID_SSA_v2.R">GitHub</a>. Ademais, muito do que foi apresentado aqui teve como inspiração o trabalho do professor&nbsp;<strong>Regis A. Ely</strong>, da Universidade Federal de Pelotas, o trabalho dele poderá ser encontrado&nbsp;<a href="http://regisely.com/blog/mercado-de-trabalho-covid/">aqui</a>. Agradeço a todos que, porventura, caíram nesse site e acharam o conteúdo interessante.</p>



<p>Aqui estão minhas redes sociais: <a href="https://www.instagram.com/cleiton._r/">Instagram</a>, <a href="https://www.linkedin.com/in/cleitonoerocha/">LinkedIn</a>, <a href="https://github.com/CleitonOERocha"><a href="https://github.com/CleitonOERocha">GitHub</a>.</a> </p>



<p>#R #Rstats #datascience #cienciadedados</p>
<p>O post <a href="http://estatidados.com.br/trabalhando-com-os-microdados-da-pnad-covid19-no-r/">Trabalhando com os microdados da PNAD COVID19 no R</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/trabalhando-com-os-microdados-da-pnad-covid19-no-r/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Criando um aplicativo desktop em Shiny</title>
		<link>http://estatidados.com.br/criando-um-aplicativo-desktop-em-shiny/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=criando-um-aplicativo-desktop-em-shiny</link>
					<comments>http://estatidados.com.br/criando-um-aplicativo-desktop-em-shiny/#respond</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 28 Sep 2020 16:28:59 +0000</pubDate>
				<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Rodrigo Barbosa]]></category>
		<guid isPermaLink="false">http://estatidados.com.br/?p=429</guid>

					<description><![CDATA[<p>Como um frequente usuário do R, em certo momento questionei como criar um aplicativo Shiny executável em desktop, sem a dependência de instalação prévia do R e dos pacotes utilizados. Encontrei dois excelentes artigos que apresentam algumas passibilidades: Deploying Desktop Apps<a class="leiamais" href="http://estatidados.com.br/criando-um-aplicativo-desktop-em-shiny/" title="Criando um aplicativo desktop em Shiny">...[Continuar lendo]</a></p>
<p>O post <a href="http://estatidados.com.br/criando-um-aplicativo-desktop-em-shiny/">Criando um aplicativo desktop em Shiny</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="467" src="http://estatidados.com.br/wp-content/uploads/2020/09/0-3-1024x467.png" alt="" class="wp-image-430" srcset="http://estatidados.com.br/wp-content/uploads/2020/09/0-3-1024x467.png 1024w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3-300x137.png 300w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3-768x350.png 768w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3-200x91.png 200w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3-400x182.png 400w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3-1000x456.png 1000w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3-1042x475.png 1042w, http://estatidados.com.br/wp-content/uploads/2020/09/0-3.png 1316w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Como um frequente usuário do R, em certo momento questionei como criar um aplicativo Shiny executável em desktop, sem a dependência de instalação prévia do R e dos pacotes utilizados. Encontrei dois excelentes artigos que apresentam algumas passibilidades: <a rel="noreferrer noopener" href="https://www.r-bloggers.com/2014/04/deploying-desktop-apps-with-r/" target="_blank">Deploying Desktop Apps with R</a> e <a rel="noreferrer noopener" href="http://blog.analytixware.com/2014/03/packaging-your-shiny-app-as-windows.html" target="_blank">Packaging your Shiny App as an Windows desktop app</a>.</p>



<p>Após algumas tentativas, criei uma &#8220;receita de bolo&#8221; que funcionou bem para mim. Irei compartilhá-la aqui, sem me preocupar com o motivo de algumas etapas, pois foram bem detalhados nos artigos citados. Este processo foi feito no Windows, mas deve ser semelhante para Linux ou macOS (nunca testei).</p>



<p><strong>1 &#8211; Esqueleto</strong></p>



<p><strong>1.1.</strong>&nbsp;Criar uma pasta para estruturar o aplicativo:</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQE7TzutQ40b1Q/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=PPZTd_tmdKcckOlSkIIDFMO5Mj5JIXuA0NcTQAHGQ2A" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p><strong>1.2.</strong>&nbsp;Baixar o&nbsp;<a href="https://sourceforge.net/projects/rportable/" target="_blank" rel="noreferrer noopener">R Portable</a>&nbsp;e instalar na pasta&nbsp;<em>executavel/</em>:</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQFudHeNpMRb0w/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=rTGilXZ91WLY6F6a3hoADB03ZJ1E11YrDvIxwhI1vKs" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Permitirá utilizar o R como um &#8220;motor&#8221; independente, sem a necessidade do usuário possuí-lo instalado no sistema.</p>



<p>Obs: a versão 4.0.0 do R apresentou alguns problemas no Windows. Caso ainda não esteja disponível a versão 4.0.2 do R Portable, baixe a versão anterior (<a href="https://sourceforge.net/projects/rportable/files/R-Portable/3.6.3/" target="_blank" rel="noreferrer noopener">3.6.3</a>).</p>



<p><strong>1.3.</strong>&nbsp;Ir em&nbsp;<em>R-Portable/App/R-Portable/etc/Rprofile.site&nbsp;</em>e, ao final do arquivo, colar o código:</p>



<pre class="wp-block-preformatted">.First = function(){
&nbsp; &nbsp; .libPaths(.Library)
}
</pre>



<p>Isso forçará o R Portable a usar apenas sua biblioteca local para instalar/carregar pacotes.</p>



<p><strong>1.4.&nbsp;</strong>Inicie o R Portable e instale os pacotes utilizados no aplicativo Shiny desenvolvido. No mínimo deve ser instalado o pacote&nbsp;<em>shiny.</em></p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQEnVceHvDGUJA/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=vDUvlWSB-k8Dx3bjn_LC270lljy9qI2hBjmL5LFwdyM" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p><strong>1.5.&nbsp;</strong>Crie a pasta&nbsp;<em>executavel/shiny/</em>&nbsp;com o aplicativo Shiny desenvolvido.</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C5612AQF0Nz4cCN88Sw/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=rSfcbIpXp98Suxoskl0zh9IqD5DncmEJtmX_yITRDro" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>A proposta não é ensinar a funcionalidade Shiny, mas sim explicar como transformá-la em um executável. Portanto, em app.R, criei um exemplo simples e sem utilidade. Note que incluí&nbsp;<em>session&nbsp;</em>como um parâmetro na função do servidor, e&nbsp;<strong>utilizei este objeto para encerrar corretamente o aplicativo quando sua tela for fechada</strong>.</p>



<pre class="wp-block-preformatted">library(shiny)


ui &lt;- fluidPage(
&nbsp;&nbsp;
&nbsp; titlePanel("Hello Shiny!"),
&nbsp;&nbsp;
)


server &lt;- function(input, output, session) {
&nbsp;&nbsp;
&nbsp; # FINALIZANDO APLICATIVO
&nbsp; session$onSessionEnded(function() stopApp())
&nbsp;&nbsp;
}


shinyApp(ui = ui, server = server)
</pre>



<p><strong>2 &#8211; Criar scripts de inicialização do aplicativo</strong></p>



<p><strong>2.1.</strong>&nbsp;Criar o script&nbsp;<em>runShinyApp.R</em>&nbsp;na pasta&nbsp;<em>executavel/</em>&nbsp;com o seguinte código:</p>



<pre class="wp-block-preformatted">chrome.sys = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'


if (file.exists(chrome.sys))
&nbsp; options(browser = chrome.sys)
shiny::runApp('./shiny/app.R', launch.browser=T)
</pre>



<p>A ideia é verificar se o usuário possui o Google Chrome instalado: se sim, abrir o aplicativo neste navegador e, se não, abri-lo no seu navegador padrão.</p>



<p><a href="https://www.r-bloggers.com/2014/04/deploying-desktop-apps-with-r/" target="_blank" rel="noreferrer noopener">Lee Pang</a>&nbsp;sugere que se instale uma versão portátil do Google Chrome, assim como o R Portable, para o caso do usuário não ter um navegador instalado. Entendo não ser necessário, por ser um programa mais comum (e também acho mais legal abrir como uma aba adicional no Chrome).</p>



<p><strong>2.2.</strong>&nbsp;Criar o script&nbsp;<em>run.vbs</em>&nbsp;para ser um botão de inicialização do aplicativo. Para tal, abra um bloco de notas e cole o seguinte código:</p>



<pre class="wp-block-preformatted">Rexe&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= "R-Portable\App\R-Portable\bin\Rscript.exe"
Ropts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = "--no-save --no-environ --no-init-file --no-restore --no-Rconsole"
RScriptFile&nbsp; &nbsp; = "runShinyApp.R"
Outfile&nbsp; &nbsp; &nbsp; &nbsp; = "ShinyApp.log"&nbsp;
strCommand&nbsp; &nbsp; &nbsp;= Rexe &amp; " " &amp; Ropts &amp; " " &amp; RScriptFile &amp; " 1&gt; " &amp; Outfile &amp; " 2&gt;&amp;1"

intWindowStyle = 0&nbsp; &nbsp; &nbsp;' Hide the window and activate another window.'
bWaitOnReturn&nbsp; = False ' continue running script after launching R&nbsp; &nbsp;'

' the following is a Sub call, so no parentheses around arguments'
CreateObject("Wscript.Shell").Run strCommand, intWindowStyle, bWaitOnReturn
</pre>



<p>Salve o arquivo com o nome&nbsp;<em>rub.vbs&nbsp;</em>na pasta&nbsp;<em>executavel/&nbsp;</em>para criar um inicializador da aplicação.</p>



<p><strong>2.3.</strong>&nbsp;Se todas as etapas até aqui foram feitas corretamente, ao clicar duas vezes em&nbsp;<em>run.vbs</em>, o aplicativo abrirá em uma aba do navegador do Google Chrome.</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQG_LuleSgP-bg/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=TB36XBKoIiXTUUp931cA8JF4_NDXGPprIfBSOd4x8Jw" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Obs: O arquivo&nbsp;<em>ShinyApp.txt&nbsp;</em>é criado automaticamente para salvar o log de dados.</p>



<p><strong>3 &#8211; Compactar em um executável de instalação</strong></p>



<p>Até o momento conseguimos compartilhar a pasta&nbsp;<em>executavel/&nbsp;</em>e rodar o aplicativo simplesmente clicando duas vezes em&nbsp;<em>run.vbs.</em></p>



<p>Essa seção busca embelezar o processo, criando um executável de instalação e um atalho personalizado para o desktop.</p>



<p><strong>3.1.</strong>&nbsp;Baixe a ferramenta&nbsp;<a href="https://jrsoftware.org/isinfo.php" target="_blank" rel="noreferrer noopener">Inno Setup</a>&nbsp;(não precisa instalar na pasta&nbsp;<em>executavel/</em>).</p>



<p>Obs: Você pode baixar um &#8220;módulo de criptografia&#8221; separado, se quiser utilizar os recursos de criptografia do Inno Setup.</p>



<p><strong>3.2.</strong>&nbsp;Salve uma imagem no formato ICO na pasta&nbsp;<em>executavel/.&nbsp;</em>Utilizarei o&nbsp;<em>ico_hello.ico.</em></p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQEcNxHq-NIZAw/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=cXgh8sk9KRYAAl_oJIoXrmT_SEryvGGF9hvMs0gOut4" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Obs: Sites que convertem PNG em ICO são de fácil acesso, costumo utilizar o&nbsp;<a href="https://convertio.co/pt/png-ico/" target="_blank" rel="noreferrer noopener">Convertio</a>.</p>



<p><strong>3.3.&nbsp;</strong>Abra um script no Inno Setup e cole o código abaixo:</p>



<pre class="wp-block-preformatted">#define MyAppName "HELLO"&nbsp; ; NOME DO APLICATIVO
#define MyAppVersion "1.0"&nbsp; ; VERSÃO
#define MyAppPublisher "My Company, Inc."&nbsp; &nbsp;; COMPANHIA
#define MyAppURL "http://www.example.com/"&nbsp; ; SITE


[Setup]
; NOTA: O valor de AppId identifica exclusivamente este aplicativo. Não use o mesmo valor AppId em instaladores para outros aplicativos.
; (Para gerar um novo GUID, clique em Ferramentas | Gerar GUID dentro do IDE.)
AppId={{E8C494FB-1AE3-45C6-8B6F-F00649056FF7}


AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName=C:\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes


; Remova o comentário da linha a seguir para executar no modo de instalação não administrativa (instalar apenas para o usuário atual).
;PrivilegesRequired=lowest


; Endereço da pasta que será salvo o instalador
OutputDir=C:\Users\Administrador\Documents\Shiny


; Nome do instalador
OutputBaseFilename=HELLO_INSTALADOR


; Endereço do ICO
SetupIconFile=C:\Users\Administrador\Documents\Shiny\executavel\\ico_hello.ico


Compression=lzma
SolidCompression=yes
PrivilegesRequired=none


; Criptografar Instalador
; Encryption=yes


; Senha, se quiser
Password=12345678&nbsp; &nbsp;&nbsp;


[Languages]
Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"


[Files]
; Endereço da pasta que será compactada com \* no final
Source: "C:\Users\Administrador\Documents\Shiny\executavel\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;&nbsp; NOTA: Não use "Flags: ignoreversion" em nenhum arquivo de sistema compartilhado


; Criar programa de desinstalação
[Icons]
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"


; Substituir com o nome do aplicativo, o nome do arquivo VBS e do arquivo ICO
[Icons]
Name: "{commondesktop}\HELLO"; Filename: "{app}\run.vbs"; IconFilename: {app}\ico_hello.ico

</pre>



<p>Segue abaixo como fica a visualização do código acima no Inno Setup. Os comentários (em verde) irão indicar os códigos que deverão se alterados para adaptar a um outro executável de instalação.</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQExOLiKsfiW2Q/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=hPPXOEKGkT9zjRWxLe9GUqrUbWSoSyKK-jYxmuroOBE" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Após ajustar o script, o execute.</p>



<p><strong>3.4.&nbsp;</strong>Será criado um instalador na pasta indicada pelo script. No meu caso o nomeei de HELLO_INSTALADOR.</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQFA91dtmz1KXA/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=0IglKCT0ZQDzIKhAF7vK3dQRU15Sozuxrcb22XdaFMY" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Caso não tenha instalado o aplicativo logo após o Inno Setup criar o executável, clique duas vezes para instalar.</p>



<p>Esse executável de instalação poderá ser compartilhado com os usuários.</p>



<p><strong>3.5.&nbsp;</strong>Após a instalação, será criado um atalho na sua tela principal que abrirá o aplicativo Shiny automáticamente:</p>



<figure class="wp-block-image"><img decoding="async" src="https://media-exp1.licdn.com/dms/image/C4D12AQFRZTLueKLJEw/article-inline_image-shrink_1000_1488/0?e=1606953600&amp;v=beta&amp;t=DHLbRZr0fsm9Bq0I1se7kl56nrQEEZLrqsa82VW_KZw" alt="Não foi fornecido texto alternativo para esta imagem"/></figure>



<p>Pronto. Temos um aplicativo disponibilizado a partir de um executável de instalação.</p>



<p><strong>Considerações finais</strong></p>



<p>De nada adianta criar um executável, se o aplicativo Shiny não tiver utilidade. Acho que ninguém irá apresentar para o chefe um &#8220;Hello Shiny!&#8221;.</p>



<p>Para uma maior aprendizado dessa ferramenta, recomendo a consulta dos seguintes links:</p>



<ul class="wp-block-list"><li><a href="https://shiny.rstudio.com/tutorial/" target="_blank" rel="noreferrer noopener">https://shiny.rstudio.com/tutorial/</a></li><li><a href="https://rstudio.github.io/shinydashboard/" target="_blank" rel="noreferrer noopener">https://rstudio.github.io/shinydashboard</a></li><li><a href="https://shiny.rstudio.com/gallery/" target="_blank" rel="noreferrer noopener">https://shiny.rstudio.com/gallery</a></li><li><a href="https://rstudio.github.io/DT/shiny.html" target="_blank" rel="noreferrer noopener">https://rstudio.github.io/DT/shiny.html</a></li><li><a href="https://shiny.rstudio.com/articles/css.html" target="_blank" rel="noreferrer noopener">https://shiny.rstudio.com/articles/css.html</a></li></ul>



<p><a href="#R hashtag#Shiny hashtag#RShiny hashtag#AppShiny hashtag#Desktop hashtag#Innosetup">#R </a><a href="https://www.linkedin.com/feed/hashtag/?keywords=r">#R</a> <a href="https://www.linkedin.com/feed/hashtag/?keywords=shiny">hashtag#Shiny</a> <a href="https://www.linkedin.com/feed/hashtag/?keywords=rshiny">hashtag#RShiny</a> <a href="https://www.linkedin.com/feed/hashtag/?keywords=appshiny">hashtag#AppShiny</a> <a href="https://www.linkedin.com/feed/hashtag/?keywords=desktop">hashtag#Desktop</a> <a href="https://www.linkedin.com/feed/hashtag/?keywords=innosetup">hashtag#Innosetup</a></p>
<p>O post <a href="http://estatidados.com.br/criando-um-aplicativo-desktop-em-shiny/">Criando um aplicativo desktop em Shiny</a> apareceu primeiro em <a href="http://estatidados.com.br">Estatidados</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://estatidados.com.br/criando-um-aplicativo-desktop-em-shiny/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
