Split code over multiple lines in an R script
Asked Answered
R

9

172

I want to split a line in an R script over multiple lines (because it is too long). How do I do that?

Specifically, I have a line such as

setwd('~/a/very/long/path/here/that/goes/beyond/80/characters/and/then/some/more')

Is it possible to split the long path over multiple lines? I tried

setwd('~/a/very/long/path/here/that/goes/beyond/80/characters/and/
then/some/more')

with return key at the end of the first line; but that does not work.

Thanks.

Rectum answered 13/6, 2011 at 11:44 Comment(0)
D
138

You are not breaking code over multiple lines, but rather a single identifier. There is a difference.

For your issue, try

R> setwd(paste("~/a/very/long/path/here",
               "/and/then/some/more",
               "/and/then/some/more",
               "/and/then/some/more", sep=""))

which also illustrates that it is perfectly fine to break code across multiple lines.

Deoxygenate answered 13/6, 2011 at 11:55 Comment(8)
Thanks! I was wondering if there was a character that I could put at the end of line to indicate to R that the code continues on the next line. Such as "\" in Python. However, your solution works well for the specific problem of string continuation.Rectum
or you better use paste0(...) which is equivalent to paste(..., sep="")Michamichael
But paste0 didn't yet exist when I wrote the answer 2+ years ago.Deoxygenate
Looks like the edit was rejected, and I more or less agree with the reject. The answer is still correct, has its context and the comments update it.Deoxygenate
Thanks for this. I mislearned that you need to use a plus to split long lines. I'm glad the reality is much simpler!Progenitive
It quite inconvenient to do word wrapping in R or Rstudio. In jupyter, just use \ to break lines.Urology
gsub( pattern = '[\n]', replacement = "" , x = 'some long text with line breaks' )Sinistrad
Using the built-in behavior of paste this way is my preferred method. I also recommend sometimes using paste0 and inserting spaces explicitly.Peen
C
184

Bah, comments are too small. Anyway, @Dirk is very right.

R doesn't need to be told the code starts at the next line. It is smarter than Python ;-) and will just continue to read the next line whenever it considers the statement as "not finished". Actually, in your case it also went to the next line, but R takes the return as a character when it is placed between "".

Mind you, you'll have to make sure your code isn't finished. Compare

a <- 1 + 2
+ 3

with

a <- 1 + 2 +
3

So, when spreading code over multiple lines, you have to make sure that R knows something is coming, either by :

  • leaving a bracket open, or
  • ending the line with an operator

When we're talking strings, this still works but you need to be a bit careful. You can open the quotation marks and R will read on until you close it. But every character, including the newline, will be seen as part of the string :

x <- "This is a very
long string over two lines."
x
## [1] "This is a very\nlong string over two lines."
cat(x)
## This is a very
## long string over two lines.

That's the reason why in this case, your code didn't work: a path can't contain a newline character (\n). So that's also why you better use the solution with paste() or paste0() Dirk proposed.

Crosscountry answered 13/6, 2011 at 13:20 Comment(7)
Thanks Joris. I saw the examples similar to the ones you have given in the some online documentation and tried that for the string too. I thought that if it does not encounter a closing quote, it will continue to the next line. But with string it does not work, or rather, as you said, works in a different way in the sense that it take enter as a new line character.Rectum
Thanks for making it clear why sometimes you can split lines with a plus sign!Progenitive
Often a nuisance with long multiline ggplot commandsChari
no, it's not smarter than python here. rather than paste("~one",\n"/two") you just need ("~one" \n "/two"). drop the commas and the paste. Not looking language smackdown. I use both languages but have always though paste was an annoyance.Temperature
@PhilCooper I wasn't refering to paste. It was a lighthearted joke. I use both R and Python, and each shines in different areas. I was just refering to the fact that you need `\` in Python to split a line.Crosscountry
@JorisMeys Right, I was trying to correct that misstatement. Use parens and you don't need the "\" for line continuation. I like it because you can also have comments on lines which you cannot do with the "\" syntax (e.g. ("one"\n "/one.one" # some comment\n "/two")' examples in #10660935Temperature
leaving a bracket open, or ending the line with an operator these two are the way to go.Lanciform
D
138

You are not breaking code over multiple lines, but rather a single identifier. There is a difference.

For your issue, try

R> setwd(paste("~/a/very/long/path/here",
               "/and/then/some/more",
               "/and/then/some/more",
               "/and/then/some/more", sep=""))

which also illustrates that it is perfectly fine to break code across multiple lines.

Deoxygenate answered 13/6, 2011 at 11:55 Comment(8)
Thanks! I was wondering if there was a character that I could put at the end of line to indicate to R that the code continues on the next line. Such as "\" in Python. However, your solution works well for the specific problem of string continuation.Rectum
or you better use paste0(...) which is equivalent to paste(..., sep="")Michamichael
But paste0 didn't yet exist when I wrote the answer 2+ years ago.Deoxygenate
Looks like the edit was rejected, and I more or less agree with the reject. The answer is still correct, has its context and the comments update it.Deoxygenate
Thanks for this. I mislearned that you need to use a plus to split long lines. I'm glad the reality is much simpler!Progenitive
It quite inconvenient to do word wrapping in R or Rstudio. In jupyter, just use \ to break lines.Urology
gsub( pattern = '[\n]', replacement = "" , x = 'some long text with line breaks' )Sinistrad
Using the built-in behavior of paste this way is my preferred method. I also recommend sometimes using paste0 and inserting spaces explicitly.Peen
G
39

Dirk's method above will absolutely work, but if you're looking for a way to bring in a long string where whitespace/structure is important to preserve (example: a SQL query using RODBC) there is a two step solution.

1) Bring the text string in across multiple lines

long_string <- "this
is 
a 
long
string
with
whitespace"

2) R will introduce a bunch of \n characters. Strip those out with strwrap(), which destroys whitespace, per the documentation:

strwrap(long_string, width=10000, simplify=TRUE)

By telling strwrap to wrap your text to a very, very long row, you get a single character vector with no whitespace/newline characters.

Grisons answered 14/11, 2012 at 18:9 Comment(4)
I like this answer most because I don't have to write so many commas as with paste, if the string is rather long. +1Lecky
Be aware that strwrap might return vector of multiple strings even if source string doesn't exceed 10k characters. Try strwrap("a\n\nb"). It will return vector of length 3 and you need to paste it back using paste(strwrap("a\n\nb"), collapse=" ") using a space character glue to collapse vector.Agitation
Can someone edit the answer to include the important information in the previous comment? I do not quite understand the issue and do not want to mess up the answer.Scoutmaster
I do not understand what “where whitespace/structure is important to preserve” means here. Does that mean preserved in the code or in the character object itself? Also, the resulting character vector definitely does have whitespace. I understand this answer to be about how to replace line breaks with spaces and then collapse each case of whitespace to a single space (except that double spaces after some punctuation are preserved).Scoutmaster
D
24

For that particular case there is file.path :

File <- file.path("~", 
  "a", 
  "very", 
  "long",
  "path",
  "here",
  "that",
  "goes",
  "beyond",
  "80",
  "characters",
  "and",
  "then",
  "some",
  "more")
setwd(File)
Dipteran answered 8/2, 2013 at 21:6 Comment(0)
B
10

The glue::glue function can help. You can write a string on multiple lines in a script but remove the line breaks from the string object by ending each line with \\:

glue("some\\
     thing")

something
Boyle answered 2/6, 2021 at 19:44 Comment(0)
W
8

I know this post is old, but I had a Situation like this and just want to share my solution. All the answers above work fine. But if you have a Code such as those in data.table chaining Syntax it becomes abit challenging. e.g. I had a Problem like this.

mass <- files[, Veg:=tstrsplit(files$file, "/")[1:4][[1]]][, Rain:=tstrsplit(files$file, "/")[1:4][[2]]][, Roughness:=tstrsplit(files$file, "/")[1:4][[3]]][, Geom:=tstrsplit(files$file, "/")[1:4][[4]]][time_[s]<=12000]

I tried most of the suggestions above and they didn´t work. but I figured out that they can be split after the comma within []. Splitting at ][ doesn´t work.

mass <- files[, Veg:=tstrsplit(files$file, "/")[1:4][[1]]][, 
    Rain:=tstrsplit(files$file, "/")[1:4][[2]]][, 
    Roughness:=tstrsplit(files$file, "/")[1:4][[3]]][, 
    Geom:=tstrsplit(files$file, "/")[1:4][[4]]][`time_[s]`<=12000]
Winker answered 28/11, 2019 at 14:28 Comment(6)
Could it be you mixed up the question you were trying to answer? This has nothing to do with OP's question.Chivaree
It does have. The main question is how to split a line of code into several lines. I demonstrated that by using another example which is abit more complex than the original question. I thought it was necessary to post it because I spent a lot of time trying to figure out how to split that particular piece of code. And I guess it help someone with a similar problem.Winker
The OP's problem was that splitting a character vector with a linebreak includes the linebreak in the character vector. Your answer is only specific to data.table syntaxChivaree
As an example of splitting a line of code over multiple linesWinker
This answer is within the scope of the question because the question is unclear. Some people know that writing a single-line string across multiple lines is a special case that deserves a separate question from how to split lines of code in general, but many of the people who will see this question do not know that. Ideally, there would be two different questions that each contained a link to the other, but there are already answers to both questions here.Scoutmaster
This is a useful answer, in scope for the general question as asked (although not the OP's particular example). A naive Google search for the general question brings up this page and it is helpful to have this solution here. Even though it is really ugly! The empty-comma syntax of data.table is bad enough, but splitting a line at it is just horrible for legible code.Dedradedric
C
2

There is no coinvent way to do this because there is no operator in R to do string concatenation.

However, you can define a R Infix operator to do string concatenation:

`%+%` = function(x,y) return(paste0(x,y))

Then you can use it to concat strings, even break the code to multiple lines:

s = "a" %+%
    "b" %+%
    "c"

This will give you "abc".

Cytochemistry answered 25/6, 2022 at 20:57 Comment(0)
C
2

I do this all of the time. Use the paste0() function.

Rootdir = "/myhome/thisproject/part1/"
Subdir = "subdirectory1/subsubdir2/"

fullpath = paste0( Rootdir, Subdir )

fullpath

> fullpath
[1] "/myhome/thisproject/part1/subdirectory1/subsubdir2/"

Cameo answered 2/10, 2022 at 13:15 Comment(0)
H
0

This will keep the \n character, but you can also just wrap the quote in parentheses. Especially useful in RMarkdown.

t <- ("
this is a long
string
")
Hogarth answered 15/1, 2021 at 1:16 Comment(1)
What are the parentheses doing? I have not found any effect of including or omitting them. This also does not seem to be answering the question, which is about how to write a single-line string over multiple lines of a script.Scoutmaster

© 2022 - 2024 — McMap. All rights reserved.