Maybe a dumb question: How can we break ggplot code into multiple lines, each line ended with +?
I tried to do that in rstudio editor, but it does not work.
Not sure what you're asking, but I'll offer a suggestion. When working with long ggplot, dplyr or other statements in rstudio, I structure the lines:
results = (dcsv
%>% mutate(sdisagree_pct = strongly_disagree / n_resp * 100)
# %>% select( Item,sdisagree_pct:sagree_pct)
%>% rename( `Strongly disagree` = sdisagree_pct,
`Disagree` = disagree_pct,
`Neutral` = neutral_pct,
`Agree` = agree_pct,
`Strongly agree` = sagree_pct
)
)
Note the parentheses wrapping the entire multiline statement. The parenthesis force R to read the multiple lines regardless of where the operator is located in the line. Also note that I put the %>% operator at the beginning of each line. With the operator at the beginning of the line, I'm able to comment out # specific lines for testing. The same structure works with a + operator for ggplot.
Related
When trying to retreive a linear regression equation I keep getting this error:
Error in eval(predvars, data, env) : object 'OBP' not found
Here is my chunk,
teams_oak %>%
select(G:FP) %>%
mutate(OBP=H+BB+HBP/AB+BB+HBP+SF) %>%
ggplot(aes(x=OBP,y=W))+
geom_point()+
geom_smooth(method = "lm")+
labs(title="OBP vs. Wins in MLB 1982-2002 ex:1994",x="On Base Percentage",y="Wins") %>%
teams_oak %>%
select(G:FP) %>%
mutate(OBP=H+BB+HBP/AB+BB+HBP+SF) %>%
m1<-lm(data = teams_oak,formula = W~OBP)
I've tried to pipe all the functions together to make sure that the code was reading for the mutated variable and it seems it cannot find it.
When you do this:
teams_oak %>%
select(G:FP) %>%
mutate(OBP=H+BB+HBP/AB+BB+HBP+SF) %>%
m1<-lm(data = teams_oak,formula = W~OBP)
on the last two lines you are using the pipe operator with an assignment on the last line. Within that assignment you are naming teams_oak as the data, but because this is in the pipe and the pipe hasn't finished yet, it doesn't have the OBP variable, so it fails.
I think simply omitting the last pipe operator and turning it into two assigment statements, should work, with a blank line and indentation to indicate the end of the pipe
teams_oak <- teams_oak %>%
select(G:FP) %>%
mutate(OBP=H+BB+HBP/AB+BB+HBP+SF)
m1<-lm(data = teams_oak,formula = W~OBP)
Personally I don't use pipes because it does make it easy to break code this way. They are not the best way to write clear code.
currently, I am cleaning my dataset (Comparative Manifesto Project) and try to compute the effective number of parties using the enp function from the electoral package (https://www.rdocumentation.org/packages/electoral/versions/0.1.2/topics/enp). However, I am running in some issues.
When I run this code:
cmp_1990 %>%
mutate(enp_vote = round(pervote, digits = 2)) %>%
mutate(enp_vote = as.numeric(enp_vote)) %>%
relocate(enp_vote, .before = parfam) %>%
mutate(enp_vote = enp(votes = cmp_1990$enp_vote)) %>%
relocate(enp, .before = parfam)
I get the error message:
Fehler: Can't subset columns that don't exist.
x Column `enp` doesn't exist.
I suppose, r thinks of the function enp as single column even though I have installed and used library on the package.
I tried it with differently rounded numbers and by using the enp command outside of the rest of the command but up until now nothing worked. Oh and the cmp_1990$enp_vote command was necessary as otherwise the enp function thought of enp_vote as categorical and not numerical value.
Sorry by the way if my code doesnt look like the nicest, its my first time using r haha.
Thanks very much in advance!
I'm trying to build a shiny app very closely based on a previous one I have (which works), albeit with a different (though similarly structured) data object underneath. After changing all the variable and object names, I got the following error:
Warning: Error in filter_impl: Evaluation error: $ operator is invalid
for atomic vectors.
I found a couple of seemingly relevant pages in my searches online:
$ operator is invalid for atomic vectors :: R shiny
https://github.com/rstudio/shiny/issues/1823
Unfortunately the $ operator error seems to be quite a general error message, and neither of these seemed to specifically address my problem. After some tinkering paring back various elements, I found I could render the plots and tables in the app, provided I didn't use attempt to filter on any of the input fields.
For instance, the following ouptut worked, fine, including the switch that allowed me to turn the whole plot on and off, and alter the heading of the graph with a text input called filter1.
output$emoPlot <- renderPlotly({
if(input$prefilterswitch == "OFF"){
df <- dtm_EMO %>%
clusterer(input$clusters)
plot <- df %>%
left_join(EMO_ALL, by = "Work_Order") %>%
ggplot(aes(x = date, y = as.factor(cluster), col = MILL, shape = as.factor(PART), text = Equipment_Description_Line_1, text2 = Work_Order))+
geom_point()+
guides(col = "none")+
ggtitle(label = input$filter1)
ggplotly(plot, tooltip = c("x", "y", "col", "text", "text2", "size"))
}
})
However, if I add line that seeks to filter on one of those inputs, like this:
output$emoPlot <- renderPlotly({
if(input$prefilterswitch == "OFF"){
df <- dtm_EMO %>%
filter(str_detect(combined, input$prefilterswitch %>% tolower()) ==T) %>%
clusterer(input$clusters)
plot <- df %>%
left_join(EMO_ALL, by = "Work_Order") %>%
ggplot(aes(x = date, y = as.factor(cluster), col = MILL, shape = as.factor(PART), text = Equipment_Description_Line_1, text2 = Work_Order))+
geom_point()+
guides(col = "none")+
ggtitle(label = input$filter1)
ggplotly(plot, tooltip = c("x", "y", "col", "text", "text2", "size"))
}
})
Then I get my error, and no plot:
Warning: Error in filter_impl: Evaluation error: $ operator is invalid
for atomic vectors.
I've had a play with rending a table output, using renderTable aswell, and get the same problem. I can use inputs, but not with functions like filter(), and mutate() also has the same problem.
I suspected that perhaps the issue was to do with the inputs, but all of the switches and text fields render find in the app, and they seem to work, just not with those functions.
That's about as much as I've been able to narrow it down. It's a little frustrating since the ability to apply multiple filters is quite important to the purpose of the app. Any help would be appreciated!
I am pretty sure that the problem is the use of non standard evaluation in filter. In
filter(str_detect(combined, input$prefilterswitch %>% tolower()))
you have input$prefilterswitch ... which normally in filter would be invalid because it is not just giving a column name from combined (even though we actually know that it is. I think there is probably a check in filter that automatically throws an error if there is a $. My usual solution to this is to create the object prior to starting your piping, so something like
prefilterswitch <- input$prefilterswitch
And then reference that in the filter statement. Also with a Boolean you don't need ==T.
Alternatively you can go into rlang.
Problem
My inline code chunk breaks when I filter() or select() a column name that has white space that I would normally define with backticks in dplyr.
Example Data
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(dplyr)
library(knitr)
library(lazyeval)
df <- structure(list(1:3, 2:4), .Names = c("a", "b"), row.names = c(NA, -3L), class = "data.frame")
df <- df %>% select(`a a`=a, `b b`=b)
```
Inline code chunk
I'm trying something like `r df %>% filter(`a a` == 1) %>% select(`a a`) %>% as.numeric()`, but I get the following error:
Error in base::parse(text = code, keep.source = FALSE) : <text>:2.0: unexpected end of input 1: df %>% filter( ^ Calls: <Anonymous> ... inline_exec -> withVisible -> eval -> parse_only -> <Anonymous>
...for pretty obvious reasons (the backticks end the inline code chunk). I could rename the columns in a code chunk after the intext calculations (I'm formatting them for a table), but it would be frustrating to have to break it up.
Costly lazyeval solution
This solves the problem r df %>% filter_(interp(~ which_column == 1, which_column = as.name("a a"))) %>% select_(as.name("a a")) %>% as.numeric(), but there has got to be a better way.
I am not sure how you are running things - here I provide an answer with respect to knitr.
There is no easy solution for this case, and the work-around of moving some code inside the chunks (as suggested in one of the comments) is probably the way to go.
For future reference and further insight, I'll still share the underlying problem and an alternative solution.
Note that knitr makes use of the following pattern for inline.code (given you are using Rmarkdown format):
knitr::all_patterns$md$inline.code
[1] "`r[ #]([^`]+)\\s*`"
Now the function knitr:::parse_inline matches this through a call to stringr::str_match_all, which will detect patterns of one or multiple non-backticks ([^`]+), followed by zero or multiple space-class elements (\\s*), followed by a back-tick.
So it will end on the first backtick following `r, more or less no matter what. This makes some sense, since the lines of input are collapsed in parse_inline and there could actually be multiple inline-code statements and plain text containing back-ticks in the resulting string.
If you however restrict yourself to some conventions, you could modify the pattern to detect the end of inline code pieces differently. Below I am assuming that I always break onto a new line following a piece of inline code, so e.g. following your setup chunk I only have the following:
Hello there.
`r DF %>% filter(`a a` == 1) %>% select(`a a`) %>% as.numeric()`
This should read 1 above here.
Then I can knit in the following way, modifying the pattern to take everything until a backtick followed by a new-line break:
library(knitr)
opts_knit$set('verbose' = TRUE)
knit_patterns$set(all_patterns$md)
inline.code.2 <- "`r[ #](.+)\\s*`\n"
knitr::knit_patterns$set(inline.code = inline.code.2)
knit2html("MyRmarkdownFile.rmd")
browseURL("MyRmarkdownFile.html")
Finding a general rule for this pattern that works for everyone seems impossible though.
I am trying to print an apostrophe for the column name below in a table using tableGrob
"Kendall's~tau"
The end result is that the whole label is italicized without the ~ and tau being interpreted:
How do I correctly specify this?
I don't think it's helpful, but this is the theme that I've specified to tableGrob:
table_theme <- ttheme_default(
core = list(fg_params=list(fontsize = 6)),
colhead = list(fg_params=list(fontsize = 6, parse=TRUE)),
rowhead = list(fg_params=list(fontsize = 6, parse=TRUE)),
padding = unit(c(2, 3), "mm"))
The column name is interpreted via plotmath in grDevices -- the standard way of specifying mathematical annotation in figures generated in R.
Again it has nothing to do with how to specify the expression itself, but here is the table constructor:
tableGrob(stats_df,
theme = table_theme,
rows = c("Kendall's~tau"))
Here's a reproducible example:
library(gridExtra)
library(grid)
data(iris)
table_theme <- ttheme_default(rowhead = list(fg_params=list(parse=TRUE)))
grid.table(head(iris),
rows = c(letters[c(1:4)], "plotmath~works~omega", "Kendall's~tau"),
theme = table_theme)
This works:
library(gridExtra)
library(grid)
data(iris)
table_theme <- ttheme_default(rowhead = list(fg_params=list(parse=TRUE)))
grid.table(head(iris),
rows = c(letters[c(1:4)], "plotmath~works~omega", "Kendall's"~tau),
theme = table_theme)
Try with a backslash in your expression like "Kendall\'s~tau". It should work then.
I tried to use apostrophe with expressions to plot in ggplot. In my database is invalid to use ' in expressions, but this worked
expression(paste(u,"'",(t),sep=""))
But this "paste" also cause bad behaviour of the subindex expression expression(U[0]). So to use both together, this one worked
paste(expression(paste("u","'",sep="")),"/U[0]",sep="")
If anyone knows a easier way, I'd be very glad.
If your apostrophe is embedded in a longer string, along with special symbols like ~, these solutions will not work. The only thing I've found to work is using regular expression substitution.
#This doesn't work
stringWithApostrophe="Matt's and Louise's diner~...and~also Ben's diner~X^2"
qplot(1:10,1:10)+annotate("text",x=2,y=4,label=stringWithApostrophe,parse=T)
Error: "Error in parse(text = text[[i]]) : :1:5: unexpected string constant"
The problem is the special characters like tilde and apostrophe happening in the same quoted segment. So you have to separate "Matt's" from "Louise's" and "~". Here's the code to do that.
stringWithApostrophe2<-stringr::str_replace_all(pattern = "([^~()*]*'[^~()*']*)",replacement = "\"\\1\"",string=stringWithApostrophe)
qplot(1:10,1:10)+annotate("text",x=2,y=8,hjust=0,label=stringWithApostrophe2,parse=T)
Plots successfully. The final expression that plotmath in R parses correctly is:
""Matt's and Louise's diner"~...and~"also Ben's diner"~X^2"