I would like to make a table in R markdown that prints a crosstabulation of two variables and includes the variable name above it and on the left side. Also, I need to print this to a PDF so I require code that is compatible with kable("latex").
Reproducible example:
set.seed(143)
x <- sample(x = c("yes", "no"), size = 20, replace = TRUE)
y <- sample(x = c("yes", "no"), size = 20, replace = TRUE)
table(x,y) %>%
kable("latex") %>%
pack_rows("X", 1, 2) %>%
add_header_above(c(" ", "Y" = 2))
Which gives the following output:
However I would like it to look like this (created in Word for example):
I am an environmental scientist trying to create a harvest simulation for oysters. I want the simulation to display two maps, one for showing the current oyster populations, and one for showing no-take zones (sanctuaries). Clicking on a plot on the map (each one has an invisible marker) should do something different depending on which map is showing. Clicking with the oyster population map should cause the population to update with oyster harvest occurring in the clicked plot. Clicking on the sanctuary map should cause the clicked plot to change is designation of open or closed.
The issue, as far as I can tell, is that all of these values reset every time an input is clicked. For example, it does not matter which map was showing previously, the "showSanctuary" variable, which is supposed to display F is the population map is up and T if the sanctuary map is up, is always set to False, its starting value, whenever a new input is clicked. The oyster population vector and sanctuary vector appear to do the same thing. How can I prevent these variables from resetting back to their starting values?
Also, I am very new to this forum, and I am not sure of the etiquette. I am going to post all of my code below absent the two scripts where I store my functions (I am certain they are not the issue), but it is a fairly lengthy program. This question relates to code between lines 70 and 152. I will post only those lines first, with the full script below it. Sorry again if that is not typical etiquette.
Lines where problem is occurring (this is inside the Server function):
#Make Reactive Values
offLim <- reactiveValues()
offLim = 0
showSanctuary <- reactiveValues()
showSanctuary = F
myOutputs <- reactiveValues()
myOutputs$outHarvTime = 0
myOutputs$outSacksTaken = 0
myOutputs$outAvgSize = 0
#React to click event
observeEvent(input$map_marker_click, {
click<-input$map_marker_click
if(is.null(click))
return()
xClk=trunc(click$lng*1000)/1000
yClk=trunc(click$lat*1000)/1000
xCor = which(coord$x == xClk)
yCor = which(coord$y == yClk)
myPlot = intersect(xCor, yCor)
if(showSanctuary == T){
if(offLim[myPlot]==1){
offLim[myPlot]=0
}else if(offLim[myPlot]==0){
offLim[myPlot]=1
}
myMap <- makeSanctuaryMap(offLim)
myOutputs$finalMap = myMap
}
else{
myHarvLim = input$amount
myMaxTime = input$effort
myMinSize = input$size
returnShells = input$shell
param = c(myHarvLim, myMaxTime, myMinSize, myPlot, returnShells)
newOysters = oysters
newDens = myDens
newShell = myShell
outVar<-localUpdate(param, newOysters, myMaxDens, newDens, newShell, nplts)
oysters = outVar$oysters
myDens = outVar$myDens
myShell = outVar$myShell
myOutputs$outAvgSize = outVar$avgSize
myOutputs$outHarvTime = outVar$harvTime
myOutputs$outSacksTaken = outVar$sacksTaken
myOutputs$finalMap = outVar$myMap
}
})
observeEvent(input$update,{
#Make sanctuary variables. Needs to be reactive to be global
showSanctuary = F #Whether the Map Currently Displays Sanctuary Areas
offLim = vector(length=nplts) #1 if plot is a Sanctuary or 0 if not
offLim[] = 0
offLim[!cond]<-NA
myOutputs$outAvgSize = NA
myOutputs$outHarvTime = NA
myOutputs$outSacksTaken = NA
myOutputs$finalMap = myMap
})
observeEvent(input$sanctuaryMap,{
print(showSanctuary)
showSanctuary = T
myMap <- makeSanctuaryMap(offLim)
myOutputs$finalMap = myMap
})
observeEvent(input$harvestMap,{
print(showSanctuary)
showSanctuary = F
myMap <- updateMap(heatVec)
myOutputs$finalMap = myMap
})
Full Script:
library(shiny)
library('leaflet')
library(raster)
library('sf')
library(rgdal)
source('updateFunctions.R')
effortLbl = "What is the maximum number of hours that you are willing to spend harvesting each day?"
amountLbl = "What is the maximum number of sacks of oysters you would harvest in one day?"
sizeLbl = "Select a minimum size for legal harvest (inches)"
shellLbl="Check to require culling on site"
ui<-fluidPage(
numericInput(inputId="effort", label=effortLbl, value=8, min=1, max=16, step=1),
numericInput(inputId="amount", label=amountLbl, value=4, min=1, max=40, step=1),
numericInput(inputId="size", label=sizeLbl, value=3, min=1, max=6, step=1),
checkboxInput(inputId="shell", label=shellLbl, value = FALSE),
actionButton(inputId="update", label="Begin"),
actionButton(inputId="sanctuaryMap", label="Set Sanctuaries"),
actionButton(inputId="harvestMap", label="Choose Harvest Area"),
leafletOutput("map"),
textOutput("time"),
textOutput("sacks"),
textOutput("size")
)
server<-function(input, output, session){
#Generate list of clickable coordinates
cedKey <- readOGR(dsn=path.expand("shapefile"), layer="LC_10_Area") #Imports Cedar Key shape file
ckCrd <- spTransform(cedKey, CRSobj = CRS("+init=epsg:4326")) #Converts shape file coordinate to longitude/latitude
matCrd=expand.grid(x=seq(from=-83.1164,to=-83.06251,length.out=moveRow), #Generates a series of coordinates within range
y=seq(from=29.2169,to=29.26528,length.out=moveRow))
df = data.frame(x = matCrd$x, y = matCrd$y)
s = SpatialPixelsDataFrame(df[,c('x', 'y')], data = df, proj4string = crs(ckCrd))
clp <- over(s[,c("x", "y")], ckCrd)
cond <- !is.na(clp$Id)
spNew<-s[cond,]
spDf = as.data.frame(spNew)
coord = data.frame(x=(trunc(df$x*1000)/1000), y=(trunc(df$y*1000)/1000))
#Initialize oyster population variables
nplts = 1600 #Total number of plots
nsize = 7 #Number of size classes (including larva)
oysters = matrix(0, nplts,nsize)
myDens = vector(length=nplts) #Total number of oysters weighted by size
myShell = vector(length=nplts) #The amount of dead shell (or other non-living hard substrate)
myMaxDens = 1000 #The maximum capacity of every plot
moveRow = sqrt(nplts) #The number of plots in a row
#Initialize oyster population with randomization
for(i in 1:nplts){
initMin = c(20,20,5,5,0,0) #Minimum number of oysters of each size at game start
initMax = c(60,40,30,20,10,5) #Maximum number of oysters of each size at game start
oysters[i,1:6]=runif(6, initMin, initMax)
oysters[i,7]=sum(oysters[i,1:6]*4)
}
oysters[!cond,]<-NA
for(i in 1:nplts){
myDens[i]=sum(oysters[i,1:6]*c(1:6))
myShell[i]=0.2*myDens[i]
}
#Set values of outputs before initial update
heatVec = vector(length=nplts)
for(i in 1:nplts){
heatVec[i] = (100*myDens[i])/myMaxDens
}
myMap = updateMap(heatVec)
#Make Reactive Values
offLim <- reactiveValues()
offLim = 0
showSanctuary <- reactiveValues()
showSanctuary = F
myOutputs <- reactiveValues()
myOutputs$outHarvTime = 0
myOutputs$outSacksTaken = 0
myOutputs$outAvgSize = 0
#React to click event
observeEvent(input$map_marker_click, {
click<-input$map_marker_click
if(is.null(click))
return()
xClk=trunc(click$lng*1000)/1000
yClk=trunc(click$lat*1000)/1000
xCor = which(coord$x == xClk)
yCor = which(coord$y == yClk)
myPlot = intersect(xCor, yCor)
if(showSanctuary == T){
if(offLim[myPlot]==1){
offLim[myPlot]=0
}else if(offLim[myPlot]==0){
offLim[myPlot]=1
}
myMap <- makeSanctuaryMap(offLim)
myOutputs$finalMap = myMap
}
else{
myHarvLim = input$amount
myMaxTime = input$effort
myMinSize = input$size
returnShells = input$shell
param = c(myHarvLim, myMaxTime, myMinSize, myPlot, returnShells)
newOysters = oysters
newDens = myDens
newShell = myShell
outVar<-localUpdate(param, newOysters, myMaxDens, newDens, newShell, nplts)
oysters = outVar$oysters
myDens = outVar$myDens
myShell = outVar$myShell
myOutputs$outAvgSize = outVar$avgSize
myOutputs$outHarvTime = outVar$harvTime
myOutputs$outSacksTaken = outVar$sacksTaken
myOutputs$finalMap = outVar$myMap
}
})
observeEvent(input$update,{
#Make sanctuary variables. Needs to be reactive to be global
showSanctuary = F #Whether the Map Currently Displays Sanctuary Areas
offLim = vector(length=nplts) #1 if plot is a Sanctuary or 0 if not
offLim[] = 0
offLim[!cond]<-NA
myOutputs$outAvgSize = NA
myOutputs$outHarvTime = NA
myOutputs$outSacksTaken = NA
myOutputs$finalMap = myMap
})
observeEvent(input$sanctuaryMap,{
print(showSanctuary)
showSanctuary = T
myMap <- makeSanctuaryMap(offLim)
myOutputs$finalMap = myMap
})
observeEvent(input$harvestMap,{
print(showSanctuary)
showSanctuary = F
myMap <- updateMap(heatVec)
myOutputs$finalMap = myMap
})
localUpdate <- function(param, locOyster, myMaxDens, locDens, locShell, nplts){
myUpdate<-updateFunction(locOyster, myMaxDens, locDens, locShell, param, nplts) #All updates done in separate script
#Set oyster pop, dens, and dead shell according to updates
oysters = myUpdate$oysters
for(i in 1:nplts){
myDens[i] = sum(oysters[i,1:6]*c(1:6))
}
myShell = myUpdate$shell
#Calculate heatmap values based on density (biomass)
for(i in 1:nplts){
heatVec[i] = (100*myDens[i])/myMaxDens
}
myMap <- updateMap(heatVec) #Create Map
return(list(avgSize = myUpdate$avgSize, harvTime = myUpdate$harvTime, sacksTaken = myUpdate$sacksTaken,
myMap = myMap, myShell = myShell, myDens = myDens, oysters = oysters))
}
#Assemble and Display Outputs
output$map <- renderLeaflet({
input$map_marker_click #Makes output dependent on map or button click (via isolate)
input$sanctuaryMap
input$harvestMap
input$update
isolate(myOutputs$finalMap)})
output$time <- renderText({
input$map_marker_click
input$update
timeString <- isolate(c("Time Spent Harvesting Each Day: ",
toString(trunc(myOutputs$outHarvTime*100)/100), " hours"))
timeString})
output$sacks <- renderText({
input$map_marker_click
input$update
sacksString<-isolate(c("Average Number of Sacks Harvested per Day: ",
toString(trunc(myOutputs$outSacksTaken*100)/100), " sacks"))
sacksString})
output$size <- renderText({
input$map_marker_click
input$update
sizeString<-isolate(c("Average Size of Harvested Oysters this Year: ",
toString(trunc(myOutputs$outAvgSize*100)/100), " inches"))
sizeString})
}
shinyApp(ui = ui, server = server)
For starters, you aren't using reactiveValues correctly. It would be something like this:
my_reactives <- reactiveValues()
my_reactives$offLim <- 0
my_reactives$showSanctuary <- F
I am trying to create a .rmd file that takes all of the pictures for a field day and the notes that was taken and create a report. I am able to get the pictures to plot but the no matter what I try the table with the notes does not want to print. Below is the loop I am utilizing:
for(i in 1:nrow(subset_Inventory_data)) {
singlept <- subset_Inventory_data[i,]
picture <- pictureLookup[singlept$GlobalID == pictureLookup$REL_GLOBAL,]
#PRINT PICTURE
plot(image_read(paste(baseURL,picture$UID,sep = "")) %>%
# image_resize("400x400") %>%
image_rotate(degrees = 90)
)
#creating table underneath picture
Categories <- c("Latitude", "Longitude", "Road Width", "Conditon", "Lock Present","Additional Notes")
sum_table <- data.frame(Category = character(),
Information = character(),
stringsAsFactors = FALSE)
sum_table <- rbind(sum_table,Categories,
stringsAsFactors = FALSE)
colnames(sum_table) <- Categories
sum_table$Latitude <- sprintf("%f",singlept$LAT)
sum_table$Longitude <-sprintf("%f",singlept$LONG)
sum_table$`Road Width` <- paste(singlept$Gate_Width,"feet")
sum_table$Conditon <- singlept$Condition
sum_table$`Lock Present` <- singlept$GlobalID
sum_table$`Additional Notes` <- singlept$General_Notes
#TRIED FLEXTABLE
ft <- flextable(sum_table)
ft <- fontsize(ft, size = 12)
ft <- autofit(ft)
print(ft)
#TRIED KABLE
print(kable(sum_table,"latex"))
}
Is there any reason this wouldn't work? I simply want to see which terms are found in the two selected columns. I figured intersect would do the job, but I'm not seeing results. If this looks alright, perhaps I have some other syntax error along the way? Do the inputs need to be in different sidebar panels?
selectInput("data1", "Choose you Input:", choices = colnames(data), selected = "PD.Risk.Factor"),
selectInput("data2", "Choose you Input:", choices = colnames(data), selected = "AD.Risk.Factor")),
Output:
p2 = intersect(x = input$data1, y = input$data2)
print(p2)
Welcome to SO! Please provide a reprex the next time - this will help to get help.
For our problem. What your snippet does is to compare not the columns of your data frame but the the strings as returned by selectInput. What you want to do is to use these strings to retrieve the corresponding columns in the data.
library(shiny)
sample_dat <- data.frame(x = 1:10, y = 5:14, z = 9:18)
ui <- fluidPage(selectInput("col1", "Column 1:", names(sample_dat), "x"),
selectInput("col2", "Column 1:", names(sample_dat), "y"),
verbatimTextOutput("result"))
server <- function(input, output, session) {
output$result <- renderPrint({
list(on_strings = list(col1 = input$col1,
col2 = input$col2,
intersect = intersect(input$col1, input$col2)),
on_cols = list(col1 = input$col1,
col2 = input$col2,
intersect = intersect(sample_dat[[input$col1]],
sample_dat[[input$col2]])))
})
}
shinyApp(ui, server)
I'm wondering whether it is possible to add a slide showing the table of contents into the document created with xaringan package? Thanks.
Update
Following lines will give you an automated Outline.
Unfortunately I do not know how to automatically reload an R script file in RStudio. If someone knows anything, please feel free to comment or answer in following Question.
The code searches for all the level 1 headers and the Outline header. Then it simply adds the headers as a list and overrides the current script. After reloading the file you have an outline.
---
```{r, echo=FALSE}
require("magrittr")
file_name <- rstudioapi::getSourceEditorContext()[["path"]]
doc <- toc <- readLines(file_name)
tocc <- character()
for (i in 1:length(toc)) {
if(substr(toc[i][1], 1, 2) == "# ") {
toc[i] <- gsub("# ", "", toc[i], fixed = TRUE) %>%
gsub("#", "", ., fixed = TRUE)
tocc <- append(tocc, toc[i])
}
}
tocc <- paste("- ", tocc[-1])
row_outline <- which(doc == "# Outline")
row_body <- which(doc == "---")
row_body <- row_body[which(row_body > row_outline)][1]
doc <- c(doc[1:row_outline], "\n", tocc, "\n", doc[(row_body):length(doc)])
writeLines(doc, file_name)
```
# Outline
---
Old Post
Since Sébastien Rochette's comment did not work for me, I created a very dirty solution with R.
I can think of much nicer solutions but this was a very quick solution. I hope I will update my answer in the near future.
---
```{r, echo=FALSE}
require("magrittr")
toc <- readLines("presentation.Rmd")
tocc <- character()
for (i in 1:length(toc)) {
if(substr(toc[i][1], 1, 2) == "# ") {
toc[i] <- gsub("# ", "", toc[i], fixed = TRUE) %>%
gsub("#", "", ., fixed = TRUE) %>%
paste0(" ", .)
tocc <- append(tocc, toc[i])
}
}
text <- paste(tocc[-1], "\n")
yy <- seq(.9, 0, length = length(text))
```
# Outline
```{r, echo = FALSE}
plot(x = rep(0.2, length(text)), y = yy * 1.035,
xlim = c(0, 1), ylim = c(-0.1, 1), xlab = "", ylab = "", axes = FALSE,
col = "#056EA7", type = "p", pch = 16)
text(x = 0.2, y = yy, labels = text, adj = 0, col = "black")
```
---