Mike Garcia | R in Pharma: Intro to Shiny | RStudio
Yes, this is going to be kind of an intro to shiny with some R Markdown Markdown and stuff mixed in there. But first, we already heard a bit about how I introduce myself. I'm Mike Garcia. I'm a data scientist with procol. You know, you've heard where and data science company, everything from talking about, you know, advisory, regulatory compliance, the planning aspect to data engineering and then through to reporting doing the data science and analytics that then informs the entire process. And I think that is a loop that goes back kind of where I fall is more on these last two doing it visualizations, running models, figuring out how to use the data to answer a particular business or science question.
And that's going to be kind of the. Focus of the workshop today is using particularly shinee for that visualization and turning your archerd into something interactive that your end user can engage with. So some quick, quick overview and some explications workshop goal is to understand, first off, what shinee is, the basics of how you structure a shiny application. And then how to make your own shiny. And if we have time, we're going to show and we'll show you how to incorporate chinee into some dashboards with the flex dashboard package.
Assumptions, not a lot on the our background, just some general familiarity will be helpful. What function is how to load it? Call it data sets and packages. Absolutely no prior experience and shiny or any kind of web technologies is assumed at all. We're going to use Chinese heavily visual.
So we're going to use plot for visualization. If you haven't used it before. That's fine. But some and I'll cover a little bit of this in kind of our first warm up module, of course, if you can to use base are for plotting. You can absolutely incorporate bizarre plots into shiny. Kind of our general structure that try to hold to is this quick intro a quick warm up the kind of shows and you refresh on joujou plot, if that's new to you.
We kind of build up a shiny app in layers that we're going to go to a fancier app with some more complex features. And then we'll do a demo at the end with the flex dashboard package. So first off, what is shiny by definition is a framework that allows R users to create interactive web apps without knowing anything about web design.
So you don't really have to think about all the underlying web technologies you just use. And it's kind of similar to learning a new package. They're a little bit.
You don't really need to know basis webdesign, but just a few basic things is helpful. So here's the one slide that I'm going to talk about. Web design, as I said, abstracts away the underlying technologies of the web design. Which are three of them? There's TML, which I'm sure sounds probably sounds pretty familiar if you haven't worked with it before. It's essentially the building block of a web page and your web browser interprets it and shows you the nice reformatted websites that were all used to their success or cascading style sheets.
And this separates the content. It's in what your app is doing or what your website is doing with how it looks. So you can control those independently, you can change the content, or you can update the theme.
So for the workshop today, we're going to be using RStudio cloud, you should have received an invite to the workspace and been able to open up your own session. That's essentially a clone or derivative of this project here. If you haven't put a question into the chat and one of our TAs can, I can help you sort that out. And just as a note to throughout the entire workshop, if you have questions popping into the chat either to get back to you, I'll try to pop in and monitor it from time to time to see if there are things that would be good to talk about overall and keep this as interactive as possible. So first thing we're going to do is start with the warm up, actually, I'm going to check in really quick just to make sure that people are generally able to access this.
If you're having problems accessing any of this material, if you could throw that in the chat now, just so I don't continue on if. If most people are not able to follow along the estimates, I'm not sure if we can see the chat. So it's a little tricky, but I do have a link to share to the actual RStudio Cloud space.
We did invite most of the people that registered ahead of the workshop today. So you should have got an email that gives you a link to the project. But if you didn't see that, we have a general link that is open, that should take you directly into the space.
And I can drop a link to that in the chat for everyone to see. Let me just pull that up. And I will put that in the chat. OK, just give me two seconds.
I think most people were able to I saw that there were over hundreds people had created their own project for this. So I think we should be good to go. I just wanted to clarify first.
All right, so start out in this. So from the main folder, click on the warm up, the warm up. Are formed.
So R&D is an R Markdown document. We'll go into a lot of the details of our markdown, specifically is. But it's essentially a way to integrate your code with text and illiterate programming paradigm. And then there's a lot of other features that will add in for interactivity with either visualizations and ultimately shiny. We can kind of go through this in just like a notebook sort of format and a few lines at a time. Loads of packages.
This is the flex dashboard package that would actually use this open. FDA is just a package that interfaces with the open FDA API to get some data. You don't really need to know the specifics about that, but fun to play around with if you haven't seen it before. And then just some tiny packages for manipulation and plotting and energy, things like package as well. So let's start out with just this is a helper function to gather some data from that open FDA API, so we're going to grab a function of gender brand name. So this will be the drug, brand name and age.
And yeah, this goes through and submits a query to some filtering on those variables, brand, gender and age, so that we want it to account for a limited to the top 10. And then we're going to submit the query and then this just does some formatting for to give the age that we want or to put age in the correct format. So now let's actually get to doing something, we're going to start with stroke katriona, and I think there might be better ways to do this, Pravda reports, et cetera. And that's exactly right. We're going to build up to that. So right now, we're just going to say we're going to hard code and say, we're looking at you, truta, and we're going to look specifically at 20 to 65.
You see that create function just creates it, puts it in the format that is required by the API. They're going to run that get adverse function. Going to combine the data, some are buying, stacking the data, so it's rawboned. And we want to take a quick look at what that looks like.
If you. And here we have a term. Column These are adverse events, the number to account and the gender. So we've got some data, let's move ahead and start plotting that, so. You're going to cover just you're not really going to focus on teaching tidy versus teaching Judy plot, but I'm just going to go over a few kind of key things to either refresh your memory or if you're new to this, the key things to follow along.
So you see, we start with a data set. And we're going to read. You can read this code just one line at a time, thinking of it as starting with the data set. And then we're doing gooby and then we're summarizing, et cetera this operator here is the pipe.
So it'll link things together, starting with the data set. And then we're going to apply this next function to address and we're going topoisomerase to the summarize the results of these two together. And so on.
Because they were grouping by term, which is that adverse event, and we're going to summarize, when you get the total count with an adverse event and we're going to move on and start building up the layers of our plot. So the grammar of graphics, it's this layered kind of philosophy to how to build up a visualization. So it start out with just kind of empty object. And we're going to add in a bar chart. We're going to tell it that we want.
We're doing something a little fancier to make the ordering how we want it. But we're going to tell it to put this on the x axis, count on the y-axis. We're going to put the coordinate the coordinates around. So instead of vertical bars, it's going to be horizontal and get some labels, apply a minimal theme.
And we just keep adding these on top of each other. So we can do all of this in one pipeline. And we get orographic.
Cool, so but that's just static. We're going to learn how to make this interactive and visual. OK, so maybe take this one step further and do it by gender. So this is pretty much the same code, but we've added one new line here. And that's the fast wrap. So instead of repeating copy and pasting all this over again.
And doing it again, filtering the male and then just filtering female. We can at the facet wrap, and we're also telling it to fill the bars or do a color vijender, so we've got you female on the left here, male on the right. And showing the distribution of adverse events. So that's pretty much what you really need to know about. Just think of it as you're building up all of these layers, we're going to have different plots using different genomes for different graphics.
You do things, but you won't really need to write any of that code yourself if you don't if you're new to plot and are kind of learning that alongside shiny. Of course, this whole thing is are more documents, I've kind of got through it as a notebook, but you know it. And you can see it as an HTML. All right, so. Now that we're warmed up, let's go in and actually talk about shinee, that's what we said, we were going to talk about.
So let's dive in. This first. I've got a series of templates here and they just progressively build up to a working shinee.
And so this first one is absolute minimal, minimal shinee app that you can have. And it has four components of. First off, you have to call the library, of course, shiny library shiny, you have this fluid page function, which is empty. There's no arguments in it yet. And we're assigning the output of that function to this you and you're giving it the name UI and similar. We've got this server, which is a function that we're defining, and it takes three inputs, input output, session, the names of the arguments, and then it's currently just an empty function.
And then finally, we're calling this shiny app on the UI in the server. So this is a fully working China, but it's a really boring. And the one thing you can do here, if you click on Next to run out, if you run in a window, it will pop up a new window for an external, it'll pop up in a browser window, can also select viewer pain. I'm going to do that just for presentation is.
The environment, and now it'll show up in this viewer pain here. So I can run that. And it doesn't says says it's listening on this. Localhost on this port, and it's busy, it's doing something look over the viewers, just empty or simply because we haven't actually done anything yet. Let's go ahead and stop that.
So let's talk a little bit about just the purpose of these different components. And then we'll actually start putting some content to solidify what those these different things are doing. So the UI is where we're going to put everything related to. What you might think of as like the design and the look and feel of the app. So different buttons and sliders and ways of input, kind of the overall layout, the structure of the app is going to go right there. The server is where most of your code is going to go.
That's going to be the code that's generating the plots that may be filtering, according to some dropdown venue. That selected and shiny app is actually what's running the app. So if you don't have that last line this year, your app will run. A quick note to a helpful tip that it's often useful when you're either building a complex app to build like a little component of it by itself, or maybe you're going through some exercise and you get really tired of copying boilerplate over and over again.
Our RStudio has something called a snippet that's built in. If you just type in shiny and you'll see this shiny app snippet that pops up that'll actually just populate your. Code your menu with that boilerplate, so that's a quick way, if you just want to test it with a particular input or something does. So we'll stop that app and open up the next one.
So this one, we're not we haven't changed anything in the lower bid. So we still have empty server and the Shiny app. What we've modified.
Now is we've added something to the UI. So this is kind of where we start to think about what do we want the app to look like when you're actually doing this in practice or something more complicated? It's often helpful to sit down with a pen and paper and actually sketch out what you want it to look like. Which components, which visualizations do you want? In which areas then? It can get a little overwhelming if you try to start building after a little complex, if you don't have a good vision of what you want it to look like. So we've got something like a title, this thing called sidebar layout panels, let's just run this and see what it looks like.
So we've got some material here, we've got our title going up here. It's kind of interesting. You might see the sidebar layout that we've specified, the position left, although it's kind of in the center. And we've got it within that sidebar layout. See, that function comprises like lines 8 through 16.
We've got two panels within one for the inputs and one for the main results, but they're all kind of stacked on top of each other. So I'm going to give you a moment or two to play around with this, I've got a couple exercises at the bottom. Yeah, moving to try moving the sidebar to the right, maybe play around. Is the order of this just kind of play around for a minute or so.
And get a feel. For this, and if you're kind of curious, is, if anyone has any ideas of why this might be. Just act and not where it's not actually putting on the left. And are we actually able to see the. The chat, the questions, unfortunately not.
I don't think for some reason, it's based on operating system. So far, though, I've seen questions for getting the link. Let's see. Let me look in and see if there's any other questions in here that we can do that.
You might be able to answer besides getting the link. And we've got one question saying, are you going to be covering shiny modules in today's presentation? Good question. Unfortunately, I don't think there's enough to go.
Time to go from absolute intro to shiny all the way to shiny modules in the 90 minute workshop. I wish I could say if anyone cares about what that is, it's just a way of kind of breaking up your codes here, getting less repetitive. You might have like a particular interface that would drop down, drop down menu that creates this visualization. And you want incorporate that into their different parts of your app or different apps, entirely different kind of modularize your code and a fira. You've written a lot of code, you probably used to do that. You write a function to do something rather than copying and pasting the same thing over again.
So there's training modules help address that, but we don't have time to get to that, unfortunately. Awesome, Thank you, Mike. I am I'm seeing if there's any other questions. And are you going to be covering interactive plots in Shiny today? Yes, that will definitely impact will. We're on part two out of five here, and by the time we get to five, we will have a basic interactive blog. Excellent, perfect.
And so those are all the questions that I can see coming in right now. So if you want to keep on going. And at any point if you'd like to pause and I can read out some questions as well. Sounds great. Yeah, so, you know, it just kind of go through this and say, let's move this to the right.
And see what happens. Unsurprisingly, it looks the same as if it was on the left, and it was Senator wise the right. Now, maybe you're opening this in a different window or a browser and you may have seen something entirely differently.
The reason for this is that the shiny recognizes what size screen, you're looking at this looking at just this kind of right portion of my screen. And it is doing that because it's small. It's kind of viewing that almost like a mobile device or a tablet. And if it placed it on the left, it would get everything would be really scrunched except for this, especially when you have a visualization in there. But if I drag this out far enough. OK, now it's at some point here, it decides, OK, that's a big enough screen and it lets me do what I want to do.
But instead of having to specify a different interface for a mobile device and a tablet and it maybe a small like Surface Pro and then a huge desktop, it just it gets smaller and it says, OK, you probably actually don't want your full interface here. I'm just going to stack. And because that's going to look better. But you can see now that's on the right, if you. It's on the left.
You can hit reload, the apsey don't have to actually stop and reload, but now our inputs are on the left. Cool so that's all the. Interface, we haven't really done anything to make it interactive at all yet, it's still just a static document, essentially.
So let's build this up a little bit, let's we still have this, you can see now it's getting more complicated with this is still a pretty simple app. And this is why it's a good idea to sketch things out in advance rather than just starting to put things in and having it snowball on you to end up with a lot of spaghetti code. So we still got our title, still got our sidebar layout, and now instead of you know, we've got our panel sidebar panel and a main panel, and within those cities, you used to just have some a little bit of text. Now we've got a new kind of suite of functions. And these input functions. And one of the keys to understanding shinee, these are the things that make these are the input side of the reactive aspect of shinee.
So we've got two inputs that we're putting in, and you'll see a lot of different sorts of input, radio buttons, dropdown sliders, and they have like some sort of descriptor and then input and all of them start with an ID. This ID is key. This is how you're going to how the rest of your code, when we start actually writing the server side code, is going to recognize these different inputs. And we give it a label, which is. Know human friendly, make sure you know. So we can read it.
And then there's different, different, different arguments depending on the books. And this particular one, we're looking at. And this is a dropdown and we're giving it. These choices, we say you can choose either seventy, 75% of the five or 90 here.
We've got a slighter input. So you'll see those first two arguments or the same effect. A lot of times you want to see people specify the name to say slider input beans come in number of bins. But now since we have a slider, we need to give it a range of the minimum value.
It can take the maximum value we can take and the default value. So that's all in the sidebar. And in the main panel, we're still not up to full interactivity where we have where, you know, you're changing inputs and you're getting a visualization that's changing. But we're showing you a couple of things that you can embed a local image. If you want to put something in or you can be both. If you do know a little HTML, you might realize, OK, that's the b.r. tag.
That's just an easy way to put that in. Right into your butt, inject some basic HTML right into your app. So stop her previously running one. And it run out. And so it's getting a little bit more like something we want, we've got at least what feels like interactive, but we can interact with it, you know, pick different numbers, move or slider around.
We actually have something to look at over here. But it's still there's nothing there's no logic in the back end. There's no, we're not running a visualization.
We're not generating a table. And we're definitely not connecting anything that we're doing here to our code that's running to put results over here. So finally, let's get on to talking about the server and switching it up a little bit here and introducing some data to play around with, this is his data package.
And this is just cholerae data from the London cholera epidemic of the 19th century. John Snow. And we're moving things, changing things a little bit here to accommodate that data, but not really, we still have our slighter input. And we have changed the range a little bit there.
But now we've got something a little bit different in the main panel. Before we had we were just loading RStudio logo and a little bit of text. Now and say, like we had the inputs up here.
Now we've got outputs. So anything you can think about your whole app is the user specify input and the app taking that input and returning is showing a specific combination of visualizations and tables and a set of output corresponding to that input. This is where all of your outputs go.
All of your outputs get wrapped in these output functions. So there's output, there's one of corresponding ones, four tables per text. If you want to dynamically render our markdown, there's an output for that. And similar to you, you have this input ID for each of your inputs, all of your output identifications have an outputted. Now, hopefully you're starting to see that you've got all of these different identifications and components.
And really, if you had that sketch laid out, you can label them with this is the idea for that, for that. And just makes things a lot cleaner to you as you're building this up if you have that. At a map in your rough sketch it out ahead of time. And finally, we have some server logic that this was empty until now. And emphasize it most, this is mostly just.
Our code. So we're going to ignore most of it for the moment or ignore these render plots and stuff for the moment. And it's. I reckon that was my dad.
That was my dad. No, no worries, reconnected and didn't lose anything great. Yes, so this is all just our code right here.
So you call of duty plot, give me the data set, we're giving it the value, telling it to you. So we're trying to do a histogram down here. We're making box plots. And that's great, and what we're doing here is now we're starting to use those labels, we're saying that we're creating this plot, but we're going to put it in this histogram.
We're going to put that in this output. So we've kind of create a space in our user interface for the histogram. And we're going to say, OK, we're going to put this there. And we wrap it in this renderPlot so that ultimately, when our inputs change, this listens to those inputs and we'll update it only when. So it's only when the inputs change that's not continually redoing.
If you change one component, it's not redoing your entire app. It's just loading the part that's computing the part that needs to be computed. Similarly for the box by.
So let's run this, see what it looks like. And we have. Something that actually looks like a useful shiny out, we've got our slider, we've got two plots here. But there's one thing missing, and you see if we're changing the number of Ben's idea, obviously, we want the number of beds in our histogram to change. And it's not doing that.
And the reason why it's not doing that is I'm just telling it to take the entire data set to get a histogram. Throw it in here, there's nothing tying it back to the number of bins that I have. And I can add that as an argument here, but if I specified the number of bends equals 10 or 20, whatever, then that's the hard coating. And I need it. I need it to listen to the input.
So finally, let's open up this last one. This is pretty similar, but I've added in to this kind of more just for you to play around with the time if you want just a different way of structuring it. So you see, instead of having just a sidebar layout, I've kind of got that nested within this tabs, that panel. So it's just a different way of organizing your app, giving if you have a lot of components. I want to break these across different pages to make it a little bit easier to navigate.
But the main thing that we want to focus on is here, where now we have a histogram and now we change it to a scatterplot. But instead of. Just filtering, putting in the entire data set, we're filtering it into this specific input that we've created.
So that water input scroll up. Right here, under this radio button input, we have an ID code, water input, so any time that radio button is change, a different. One is selected. That's going to make this function here is listening for that change. And when it changes, it's going to rerun this bit of code with that value of water input. So if you're going for know you're just playing around with the data set and you build up some plots, you can often just stick your coexisting code directly into your server function, you know, wrap it and renderPlot and usually just need a change if you want, or maybe sometimes more inputs to instead of, you know, instead of doing it by water input, you have to prefix it with input sine.
And you'll see over here in our original code two, there's the input. Now instead of just histogram, we're showing the listening to that the bean count graybeal. Now, I can do this. And it's doing what we expect, yeah, George ubinas, a lot of beans.
Now it's broken up instead of having another plot underneath here, it's like, OK, you want to look at scatterplot and we want to look at the scatter plots of a number of houses by death rate and do this separately for each water source. Now, here, this is where I'm selecting like New River now selecting that water input ID is changing and this is really running. So and then it's outputting it to. The object name scatterplot, which we've selected here, and that's the core logic within China, you have inputs that have identifications when those change the.
Server functions that listen for them recognize that change, recompute the visualization based on that change. And then output it into the slots that you've specified these outputs with the corresponding ID. So that concludes this module kind of building up the logic, everything from this point on is going to be kind of playing around with different ways of laying things out, maybe a little bit more complex apps and more interactivity. So check in here and see if there are any questions. Yeah, mike, let me quickly take a look and see what are some things that we've got that you can quickly discuss. See? yeah, here's one.
So do you have any tips for naming ids? They say they think this becomes important for more complex, shiny apps when there are many identical widgets, I.e., many text inputs. Yeah, definitely, and I think that's kind of one of the areas that can really snowball quickly, especially if you are playing around with the data set and you make a couple of quick shots and you're like, oh, let me turn this into a shiny, shiny app and you create a simple, shiny app like, oh, that would be cool if it did this and it would do this. And then pretty soon it can be pretty easy to have some monster with a bunch of different inputs that are interacting and really complex ways. And again, that's why I just kind of stepping back and have it like once. And that's totally fine for interactive, just building things out, prototyping.
But at some point, you have to step back and be like, whoa, this is getting more complicated. Take a step back and refactor it out, have a better layout, try to identify, you know, are you how do you have redundant inputs? Can some be combined. And then sit back and take a few minutes, like make that sketch, think about how the different parts are interacting.
And then if you really, truly do have like identical code, like maybe say we were just creating like the same like histogram over and over again, but it was just getting replicated in a lot of essentially the same code was getting replicated in a lot of different. Parts, then? The was earlier question about shiny modules that would be a solution to that. Cool Thank you. And then I have I see one other question coming in here, which would be a good one to discuss, is, what are some good ways for hosting shiny apps? For example, can it be hosted on github? What are some recommended services that you would say for hosting shinee? Yeah, another great question to cover this a little bit in the wrap up, too, but there's a few different options. Ultimately, tiny apps are just web apps and they can be run on any server.
So right now I'm just running that locally while it's on our Cloud. But it's just using that Cloud server as a local server. You can do the same thing on our studio, your desktop browser.
The obvious limitation is that you can't share it with anyone or to share. You have to send your code. They have to have all the answers to do all the right packages installed, have to run it.
There's some easy ways with shiny apps. Then there's also within RStudio enterprise suite of software. There's RStudio Connect that allows you to essentially, I'm not I don't believe I'm connected to a server right now, but you can publish a shining out just right from RStudio. And then if you have time for one more question, cool, I have a couple more, but it's all.
However many questions you want to take right now. Another one is, how do you parameterized shiny apps, for example, if you wanted to run the same report, but for different segments, is it easy to do this? How would you do that? That is a good question. In some sense, Danny is kind of taking care of the primaries because it allows you to select different values, but say you wanted the same plot. And you are the same, but you only wanted it limited to a particular year. Particular data set, particular time frame. Actually, it might bounce this to fail.
There Yeah, I'm here, I'm here, I just I'm not sure if I'm able to submit through the chat box as the person overseeing it. So I sent a link to Samantha, and there's a couple of different ways to dive into this question. I think how I would tackle it is integrating R Markdown with shiny.
And so really what you end up doing is using R Markdown as the report template or the report engine for your shiny m. And so in the example that I just sent, Samantha, what it lets you do is basically use the cat. Oh, OK. Is in the Jack.
Fantastic so basically, you can use the option and shiny there within this application that I'm shared through the chat box and it will let you pick different variables or different parts of the data that you have. And then what it will do is dynamically and reactively change the visualization. And then for that state, you can actually use R Markdown in the server folder to x or excuse me, in the shiny apps folder to actually use R Markdown to generate reports.
So this is a nice example of how you can use R Markdown is kind of the behind the scenes report engine and gives you that capability of generating reports directly from your shiny app. And is another reason why in the workshops, sometimes I'll really try hard to make sure people understand the connection between R Markdown and shiny, not only because you can turn R Markdown reports into shiny apps, but because of this other way to approach reports via shiny apps and using R Markdown. So yeah, so that's probably how I would tackle it, but there there's definitely other ways to go about this. And so.
Yeah, but but that one's pretty simple in a nice, clean example to work from. Well, thanks, bill, and yeah, and actually we'll have an example on that, that format of turning R Markdown document, embedding shiny into it at the end of the workshop. Yeah, yeah, Yeah.
I guess know, I think I saw one other question I can answer quickly about using custom plotting code. And the answer is yes, we're using kind of building up our own custom duty plot here. If you wanted to use a base. or a different. An entirely different library for visualisations, you can put that code in here, it's just whatever output that duty plot base are, ottley, whatever it puts out is going to get passed through an appropriate render function that will then place that output in the right spot of your app.
So absolutely. You can create. That's the idea behind that. You can create your own custom visualizations. And, of course, make them reactive and dynamic.
Cool, so I saw a few more questions come in, but mike, how are you feeling about time? Should we go ahead and maybe take a five minute break? Do you want to keep on chugging through? Do you want to do some questions? It's what do you feel like doing right now? All right. Yeah, maybe now would be a good time for a break, and then, like I said, we've kind of at this point, we've covered the core concepts and then from now on, it's just kind of making it cooler layouts, more complex interactivity, that sort of thing. Let's take five minutes. Now Perfect we'll take a five minute break and then let's join again at its 253 right now. So let's go ahead and join at 3 o'clock.
But we'll probably have to be wrapping up probably around three, 30 at the very latest. Sub-group great. Sounds good. So with that, then I'm going to hand it over to Kevin, if Kevin, you want to just go through and show that video again, or maybe do any overview on pricklier, and we will give Mike a break. Thanks, Samantha.
And I will go ahead and share my screen again, and I might actually, instead of just playing the slide silently, if there's anybody who's hanging around during the break, I can walk us through slides. So, again, Thanks to everybody for sticking around for this farmer excession as part of the RStudio global event, I hope everybody's signed up for different seminars and presentations throughout the global event. It should be pretty interesting, and I'm really excited to see how it's panned out. And I hope when things are back to normal, we retain some sort of global element to this conference, because I think it really provides a really good opportunity to be a bit more inclusive of people around the world who can't make it to the physical event. But with that being said, I just want to give a quick talk through of precognitive for anybody who's still around. And again, these slides were flashing around earlier, but just to reiterate what Mike had said at the start of his presentation, how we're entering data solutions provider.
So, again, we mainly concentrate on the data space. So if it has nothing to do with data, that's where we're interested in having an impact. And so we started off as a consulting firm focusing on data science and making an impact there. But we quickly realized that in order to provide true value to your customers, you've got to really be involved from the start. And there's just too many important moving parts from the start to the beginning.
So from that advisory stage where you're talking about planning out of what your architecture is going to be, a lot of companies moving from on premise infrastructure to on Cloud infrastructure or maybe just moving from Excel sheet to databases and whatever stage of the data journey they're at. We like to meet with clients, figure out where they're at and where they would like to go to and help them architect that solution. And we've started to help them, then actually setting up that infrastructure to our engineering practice. And then where it gets really interesting and fun is where a lot of things.
I think of the people in this conference, in RStudio conference and final conference are interested in, and that's around the business, intelligence and data science and analytics. And that's where we have a lot of people who work for us and a lot of knowledge in the open source data science to that. So a lot of R users and our company, python, and we like to help our customers again, insights through dashboard development, whether it be through RStudio or other platforms like powered by there as well, is a very popular one these days.
And yet, as Mike is walking through here on the shiny apps and a lot of our organizations, especially in the farm industry of these shiny and I can't blame them because it's a fantastic to really allows a lot of flexibility. And it's maitua choice. If if I had the choice of which two of you. It's the one I always tend to gravitate towards that. And of course, the more data science, more advanced analytics that you can get to do, where you set up some predictive and prescriptive analytics, where, you know, we're not just telling you where your data is going, but we can help you figure out what to change in order to gain the kind of outcomes that you desire inside of your business operations.
Very popular, I think, in the manufacturing setting is this to get into machine automation and stuff like that. I think that's where prescriptive analytics is going to have a big impact. And that obviously impacts the farm industry with respect to their manufacturing processes, et cetera.
So, yeah, a lot of really exciting things going on, data, science, analytics, and specifically with prescriptive analytics. And that starts to take hold. I think we'll see some really amazing innovations in pharmaceuticals. So just some of the areas that you can get in touch with and using data science machine learning to help improve patient care, help improve effectiveness of drug trials, become more targeted in your sales, marketing and, of course, accelerating drug discovery and development, which is a very popular use case for artificial intelligence in the fashion industry right now, using the likes of neural networks, et cetera, to really gain the power of data science and high compute power to come up with some really cool innovations in the drug space. This is just a quick overview again of the general approach that we like to take a look at that's similar to that first night I showed that where we go end. And so it's all about figuring out where your business is and where it wants to go to.
And after we've done that, we've kind of assessed what kind of needs you have to put in the plan in place to move your company towards a more data driven approach. And to our approach and partnership. We're able to drive some actual insight there.
These are just a sample of some of our previous clients, existing clients and key partners that we work with. So RStudio being the main one on showcase today, we love working with those guys and helping evangelize for RStudio and team suites, which we believe is one of the most powerful integrated environments for analytics and data science out there. And we do a lot of work hoping to apply that on Cloud.
So would it be obvious or. Sure, jur? We we think that this is the way forward for RStudio deployments and really helping lifescience partners move to the Cloud. Security is a big focus for us. Full and it looks like with that, we are exactly at the top of the hour, why don't we have it? Go ahead and I'll hand it over to mike, who's going to take us on our final sections with shinee for the last 30 minutes of today's workshop. So, mike, I'm going to make you the presenter, and it's great to have you back.
Oh, OK. And my screen smoother than last time, it looks like it mastering shiny screen right now. Yes, exactly. So I saw one question about downloads and none of this is built into the material in the webinar. But I just want to quickly say that, yes, you can upload and download.
And this is kind of a go to reference book, mastering shiny and essentially works by. You know, there's a history of it within your interface, you specify download buttons and links, those get connected to actions. So that when you click on them, it triggers in this case. Right, ESV, to a specific location of your input data set. But you can also do the same sort of things like saving images. So, yeah, check that out if you're interested in learning more about that and be connected here.
And go figure. So actually show an example of a different way to say, if you just wanted a different way, that as a side effect has allows you to download a plot, there's kind of also ties into the question of why can you use customized graphics? You different packages. Say you wanted to let's just run this. Those fancy app, the first gapminder are just run this app. You just scroll through, you can see that it's quite a bit more complicated.
And we'll go through that kind of section by section here in a minute. But it's a bit more helpful, I think, just to look and see what it actually does. And then when we get to different sections, you can tie it back to what's happening in the running app. So we've got a slider, very seen that before. In this case is filtering on year. So now we're now we're looking at between year 1973 in 2011 and we're selecting a country.
So we're looking at just marocco. And in other countries, it's showing year versus life expectancy. And we're also showing this is we've only showed plots before.
And we're doing a bit more complicated things for our set as well, so we're using this gapminder data. Of course, gapminder has a lot of countries other than these, and we're also doing so kind of collapsing. Regions, so North America doing some wrangling, some preprocessing.
And and all of our other apps, we've kind of done everything with it, there's been it's like library shiny big UI block, a big server block, and then the last line runs the app. If you do need to do some pre processing, you can do in two ways. You can use your data set beforehand and just call that data sets ready to go. But if you need to do a little minimal pre processing within the app, you don't necessarily want to include that in the server function because it might get called more times than it needs to be in that results in your app being a little bit slow and less user friendly. Sorry, I'll try not to do that. I'm sure the behind the scenes sure things are going OK.
So sorry about that. Yeah, awesome. Appreciate it, bill. Yes, so here we're doing some again, if you don't know, plier, don't worry about this, but just think about this.
And we're just doing some data wrangling. We're specifying the countries that we want to how it's West. We're mutating and creating this region group with the case when statement SQL. It's kind of analogous to that, to that if it's the regions in West west, if it's in these countries, we're calling it East Asia, et cetera. Yeah dropping some missing data, creating a couple of new columns. And we have a new data set to work with called gapminder.
And then we switch into our shiny stuff. we've got our user interface and then down here serologic. Let's run this again and get it going. So, yeah, we got our input and your input that's here. And that's going into this slider.
We've got to drop that drop down. We've seen those before selected and put selected slider input. And we've got our main panel, which we're calling the output cool.
You can call this whatever you want to, but obviously, if you're building this up, something more complex, cool is not going to be really descriptive when you come back to your code later or someone else looks at your code and tries to figure it out. But any string. There's going to be, you can give it any name that you want. This is new, so we have our output. We've got our plot output. We've seen that before.
But the table that we've got down here needs a different output showing he's not going to know how to process that as a plot because it's not a plot image. we give it you know, we have this function dt output. And of course, finding within the server, we've got this chunk here, it's called render plott doing some filtering. You know, we're not redoing all of that data, ranglin, that we did up above. We're taking starting with the output of that data Rangeley and we're doing some additional filtering.
So that's the filtering based on where we put these sliders. In this case, we got that input. Your input. You can see it's actually now a list of length 2 the first element's going to be that lower end point. Second 12 is going to be that upper endpoint.
And you're filtering for years in between. And then we're taking in another country input here. We're doing that filtering and then we're creating our plot. We're doing a similar sort of thing for the output and instead of render plot, we're doing rendered. So we're creating this new data set called filter, as is just a data frame. And Where any time one of these inputs changes, it filters a data set to just that.
And then renders that in the slot that we specified for our table to be. And then, of course, I always need this at the end to actually run your out. I'm sure one thing really quickly say say you're familiar with the plotline library. And you want to turn this into instead of a jackpot part, you want to make this interactive, turned this into a polygraph, you can actually do that really easily without, you know, probably modifying just three or four lines of code. So we're going to call the lottery library.
And when we go down here, instead of plot output, there's a whole plot layout put out a couple of lines there. Similarly with this, we've got instead of render plot, we need to do render plotless. And then probably has a function called. Shortly that will convert a plot object to a party object and find the simplest way to do this is actually just to give you a plot to save your plot as you'll give it a name and then. We can just now we have that same plot, same guy plot that we had before.
Now we're just going to turn that into a plot. We object. I think we read load this. Here we go.
Because, see, now we've turned this into a plotline object with everything that comes with ways we can hover over the points. And I mention this because if you wanted to download a copy of that quote, we have that built in. That's probably not the official solution for upload download. But if you just need one plot downloaded, that's also kind of a hack for that.
And again, there was only maybe four or five lines of code to change, to be change their. Do we have. I like to spend a little bit of time on the last module, and since it's kind of going through all these without kind of being able to wander around and look at everyone's screens and help out, I'm going to skip over this exercise. But because you look at if you're. Yeah want to.
Play around a little bit more and kind of see your understanding this, if you go ahead and run this as is, of course, it's not going to run. It's got a bunch of kind of underscores. It's placeholders. So if you go through an. There compared to the previous one for certain bits, and then this will build up a more complicated map with adding in some more functionality and to go through that.
And on your own time if you're interested. So finally going to move on to flexdashboard. And this is kind of taking a step back a little bit know we started out with R Markdown that went into shiny apps. And we have this structure with the user interface and server and inputs that are specified in the user interface.
What those change server logic is watching, listening for that. And then it reruns, whatever code or visualization that you've got based on those inputs and outputs it to your final output in your app. We're going to go back here. And actually, this is just a strict R Markdown document. And this kind of gets back to that question that we had earlier about parameter.
So this right here, we're going back to our original data, looking at adverse events. This is exactly the same. In fact, it's almost exactly what we we're going to recreate that R Markdown down in a flex dashboard format. So there's a couple of things here. Output is specified. Selex dashboard specifying the or it's going be in columns, specify that zeros just depending on how you want to organize your app.
This are code here is all the same. Your normal, R Markdown chunks. Again, we've seen that before. And OK, now we've got some new stuff. We've got columns with labeled two headers, these dashes. And then.
Within that, we've got these level three headers, the hashtag was finally, all advanced age range events by gender, and this is specifying columns within our dashboard. And this is specifying another column. And we're going to put two rows within that. So building up this grid sort of layout. And if we run it or actually R Markdown down, we're going to Netlify. Going back here, you see, I didn't actually put any code in here, this isn't outputting any grass or anything, so it's all empty right now.
But we've got that first column and then second column with two rows in it. And it's kind of this is instead of having the user interface, you're specifying the layout within this flex dashboard. Package, this structure specifying columns and rows of.
That's kind of the basic skeleton for setting it up. What's go to adverse events. And we got pretty much the same thing here, we've added a new thing here, a parameter. So this is parameter as report on this case, we're specifying it for aspirin. Again, our code to get the data and execute query at age range. And now we've got that same column, all events and column with age range and events by gender, the same structure.
But now we're going to. Do a little, you know, put some cloths in here and, you know. Put a little bit of information on what age, we selected that sort of thing. So it's. Look at this moment to load. So you can see the parameter that we specify, no drug aspirin is there.
We've got our age range in that upper limit specified use an icon in there. We've got our two plots, and that's great. Kind of cool, clean looking interface as parameter presbyteries. So say we want to go.
Back and run this. Stay on Tylenol. It's parameterize, it's going to run that give given a minute there, but of course, it's reproducibly easy to regenerate for different drugs, but it's still obviously not as friendly and not as interactive, interactive like Kashyap is. OK, so here we go. Now we've got it for Tylenol. So let's go to the last example here, so adverse events, shinee.
We're going to take that. Previous dashboard that we had and turn that into an interactive one where instead of having to specify, you know, your drug as a parameter, you can just select it and a quick scroll through. It looks pretty similar to what we had before in terms of layout.
We've got these columns of rows specified inside and we've got all of our, you know. Joujou plots to build up the visualisations, get some more stuff going on up here. I can go through all of it, but you can see that we're specifying a shiny runtime is going to allow us to embed shinee right in the dashboard. This is all the same, grab our data. And now we've got this first column, which are formatting as a sidebar.
And so you can see this is shiny. It's the text. We've seen slider input before. Text input is allows us to directly input text. And this is our input ID and that's going to be our label and the default value slider. But you see, missing from this entire thing is the UI and again, flexdashboard.
And Shiny is taking care of that for you in the background. And you're just specifying your inputs here. You're creating a new data set, and it's wrapped in this reactive statement, and that reactive turns this into from just regular code to a reactive object that listens for changes in your input. In this case, we're looking at that slider and saying, OK, we're going to whenever the upper lower end point changes, we're going to recreate that that age label. And then same thing with male and female. So then we have a male or female for that particular age range of drug.
And then going down here instead of just Rg plot, like we had in the last regular Flex dash, for example, we've got everything wrapped in random plot. And again, this isn't within server logic. And this is all taken care of for you under the hood. And you can just quickly take whatever plot you've got.
You have you've developed the prototyping and have maybe had a little bit of filtering or wrap it and renderPlot and you can embed it right within your inside your dashboard. So let's run. Documents and so this looks kind of the right. Part of this, ignoring that left column looks exactly like what we had before. We got to age range our plots. The main distribution bar chart for adverse events, but now say we want to go back and look at aspirin.
Enter and get out. I think we looked at truta. Actually, there we go. So now we've got that interactive flexibility. They've built up into that dashboard structure where they will quickly.
This is running as a shiny document. So the flex dashboard itself is the regular dashboard is an HTML that you can send to someone else. They can open it up in their browser. This does require a server that's running are and kind of one of the. Solutions that we briefly touched on using shiny apps or RStudio connect, posting it on your own in some way.
So this does require a server to be running shiny. And looks like we've got about 10 minutes left before a hard stop, so let's see if anyone has any questions. I'll take a look and see what we've got in the chat. Here, I've got one.
So what is a good way or a recommended way to test shiny apps? Do you use the Shiny test package? Oh, yeah, good question. So on one, I guess there's shiny UPS are made of a whole bunch of things. You've got the stuff that's specific to shiny and kind of how it's all taxed together in the reactive programming. And of course, you want to test, and then you might as you build up a more complex app, you might also just have regular functions that you're importing.
And that doesn't do a particular task. And you want to make sure that those are the same. So then, of course, no good programming practices are important in developing and documenting those functions. And you. We've already heard in the session about things like oxygen and tests that to make sure that you're documenting and testing, testing code that you previously ritt, you've previously written as you update and make modifications, the shiny test package is also great.
We'll run a bunch of tests on your own. On your shiny map as it all integrated, so that instead of having to, like spin it up, have a bunch of people, different people look at it. And someone be like, oh, like this drop down menu doesn't update this graph in the right way or this isn't working. Or you go here, and then there. And then all of a sudden, it breaks.
It does a lot of that sort of testing for you. So I think that's also a good path for testing. Great, Thank you. And then I think we have enough time for one more question, and it looks like Carlos answered it in the chat, but I loved his answer. So let me go ahead and ask this question as well.
And Carlos, if you want to jump on and answer as well, you're welcome to. But let's say you have a quite expensive set of function. Is it better to interactively if when each interaction is triggered or put it externally outside of everything? I imagine a situation in which you could have many of them. So putting everything outside, putting everyone outside could be slowing down the startup. But the navigation will be smooth as the opposite of making the startup quick, but slowing down the usability in that situation. What would be a good strategy to refactor the.
Hi, can you guys hear me? Yep, yeah, yeah, that is a very interesting question, and when I was touring with I was thinking, how would I do that. So far for small applications like the ones that Mike has been showing, I don't think it would be an issue of having the functionality of the app inside of the application or outside application as a practice. I normally tend to build the delivery processes before the data goes into the app, and that is applied to any other kind of visualization work that you do like.
And I would recommend to use a database to do all of that work before the data goes out. Yeah, that's awesome. Thank you. Thanks, Carlos.
Yeah, exactly, that's putting it kind of as a general rule of thumb, putting as little as possible in the server logic, because that's what it's going to get triggered interactively and then doing as much as possible before you even go into the app. So, yeah, a wrangling, processing, modeling that can be done before that can be done beforehand. And then you just put in the clean bill and clean data set. That's a full speed it up as well. Yep, I just shared a link with Samantha about Joe James keynote at the 2019 RCU conference, where he talks a lot about scaling shiny and managing it and production. And so it's a really good talk.
And it also talks about the things that Carlos just mentioned. So so, yeah, yeah, well, we're on that topic. All time, so this as well, you will see my screen here. The resources slide. Yes and then I also saw the talk tanks talk YouTube in the chat for everyone. OK, awesome.
Yeah, like I briefly showed this mastering shiny book, which is a great intro and kind of getting a broad overview here, really going into those issues of like trying to do stuff at production grade this book, I'm actually not sure if that's been fully released yet. Might still be a work in progress is also a really good source for those sorts of problems. Wonderful Thank you so much, mike, and Thank you to everyone here.
Let me quickly wrap this up for everyone. So thank you again to everyone that has joined us today for the R RStudio global are in farma excession brought to by prokaryote. If you haven't registered for RStudio global, which I hope most of you have, go ahead and do that now are 24 R marathon of events kicks off on Thursday for everyone that did join us today. Materials will be available on materials and videos for sessions that we can share will be made available for you via email and online following RStudio global conference. I've saved most of the questions here. So if there's any that we are able to follow up on, we can do that through RStudio Community.
And once again, Thank you to all of our wonderful presenters today for sharing all of their industry expertise. Thank you, everyone, and we'll see you at global.