Dividir código en varias líneas en un script R

137

Quiero dividir una línea en un script R en varias líneas (porque es demasiado larga). ¿Cómo puedo hacer eso?

Específicamente, tengo una línea como

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

¿Es posible dividir el camino largo en varias líneas? Lo intenté

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

con returnllave al final de la primera línea; Pero eso no funciona.

Gracias.

Curious2learn
fuente

Respuestas:

108

No está rompiendo el código en varias líneas, sino en un solo identificador . Hay una diferencia.

Para su problema, intente

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

lo que también ilustra que está perfectamente bien dividir el código en varias líneas.

Dirk Eddelbuettel
fuente
13
¡Gracias! Me preguntaba si había un carácter que pudiera poner al final de la línea para indicarle a R que el código continúa en la siguiente línea. Tales como "\" en Python. Sin embargo, su solución funciona bien para el problema específico de la continuación de la cadena.
Curious2learn
14
o mejor usa paste0 (...) que es equivalente a pegar (..., sep = "")
gkcn
31
Pero paste0aún no existía cuando escribí la respuesta hace más de 2 años.
Dirk Eddelbuettel
Parece que la edición fue rechazada, y estoy más o menos de acuerdo con el rechazo. La respuesta sigue siendo correcta, tiene su contexto y los comentarios lo actualizan.
Dirk Eddelbuettel
Gracias por esto. Aprendí mal que necesitas usar un plus para dividir las líneas largas. ¡Me alegra que la realidad sea mucho más simple!
Iain Samuel McLean Élder
144

Bah, los comentarios son demasiado pequeños. De todos modos, @Dirk tiene mucha razón.

R no necesita que se le diga que el código comienza en la siguiente línea. Es más inteligente que Python ;-) y continuará leyendo la siguiente línea cada vez que considere la declaración como "no terminada". En realidad, en su caso también pasó a la siguiente línea, pero R toma el retorno como un carácter cuando se coloca entre "".

Eso sí, tendrás que asegurarte de que tu código no esté terminado. Comparar

a <- 1 + 2
+ 3

con

a <- 1 + 2 +
3

Por lo tanto, al distribuir código en varias líneas, debe asegurarse de que R sepa que algo viene, ya sea:

  • dejando un soporte abierto, o
  • terminando la línea con un operador

Cuando hablamos de cadenas, esto todavía funciona, pero debes tener un poco de cuidado. Puede abrir las comillas y R seguirá leyendo hasta que lo cierre. Pero cada personaje, incluida la nueva línea, se verá como parte de la cadena:

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.

Esa es la razón por la cual en este caso, su código no funcionó: una ruta no puede contener un carácter de nueva línea ( \n). Por eso también es mejor usar la solución con paste()o con paste0()Dirk propuesto.

Joris Meys
fuente
Gracias Joris Vi ejemplos similares a los que ha proporcionado en la documentación en línea y probé eso también para la cadena. Pensé que si no encuentra una cita de cierre, continuará a la siguiente línea. Pero con string no funciona, o más bien, como dijiste, funciona de manera diferente en el sentido de que toma enter como un nuevo carácter de línea.
Curious2learn
¡Gracias por dejar en claro por qué a veces puedes dividir líneas con un signo más!
Iain Samuel McLean Élder
8
No, no es más inteligente que Python aquí. en lugar de lo paste("~one",\n"/two")que solo necesitas ("~one" \n "/two"). soltar las comas y el paste. No busco el lenguaje smackdown. Uso ambos idiomas pero siempre pensé que pegar era una molestia.
Phil Cooper el
2
@JorisMeys Correcto, estaba tratando de corregir esa declaración equivocada. Use parens y no necesita la "\" para continuar con la línea. Me gusta porque también puede tener comentarios sobre líneas que no puede hacer con la sintaxis "\" (por ejemplo, ("one"\n "/one.one" # some comment\n "/two")' ejemplos en stackoverflow.com/questions/10660435/…
Phil Cooper
1
leaving a bracket open, or ending the line with an operatorestos dos son el camino a seguir.
SIslam
35

El método de Dirk anterior funcionará absolutamente, pero si está buscando una manera de incorporar una cadena larga donde sea importante preservar el espacio en blanco / estructura (ejemplo: una consulta SQL usando RODBC) hay una solución de dos pasos.

1) Traiga la cadena de texto en varias líneas

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

2) R presentará un montón de \npersonajes. Elimine esos strwrap(), que destruyen los espacios en blanco, según la documentación :

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

Si le dice a strwrap que ajuste su texto en una fila muy, muy larga, obtendrá un vector de un solo carácter sin espacios en blanco / caracteres de nueva línea.

Andrés
fuente
3
Me gusta más esta respuesta porque no tengo que escribir tantas comas como pegar, si la cadena es bastante larga. +1
user3032689
3
Tenga en cuenta que strwrappodría devolver el vector de varias cadenas incluso si la cadena de origen no supera los 10k caracteres. Tratar strwrap("a\n\nb"). Devolverá el vector de longitud 3 y debe pegarlo nuevamente paste(strwrap("a\n\nb"), collapse=" ")usando un pegamento de caracteres espaciales para contraer el vector.
Gedrox
18

Para ese caso particular hay file.path:

File <- file.path("~", 
  "a", 
  "very", 
  "long",
  "path",
  "here",
  "that",
  "goes",
  "beyond",
  "80",
  "characters",
  "and",
  "then",
  "some",
  "more")
setwd(File)
G. Grothendieck
fuente
0

Sé que esta publicación es antigua, pero tuve una situación como esta y solo quiero compartir mi solución. Todas las respuestas anteriores funcionan bien. Pero si tiene un Código como el de la sintaxis de encadenamiento de data.table, se convierte en un gran desafío. Por ejemplo, tuve un problema como este.

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]]][veces]<=12000]

Intenté la mayoría de las sugerencias anteriores y no funcionaron. pero descubrí que se pueden dividir después de la coma interna []. Dividir en ][no funciona.

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]
M Terry
fuente
¿Podría ser que confundiste la pregunta que estabas tratando de responder? Esto no tiene nada que ver con la pregunta de OP.
zerweck
Lo tiene. La pregunta principal es cómo dividir una línea de código en varias líneas. Lo demostré usando otro ejemplo que es un poco más complejo que la pregunta original. Pensé que era necesario publicarlo porque pasé mucho tiempo tratando de descubrir cómo dividir ese código en particular. Y supongo que ayudará a alguien con un problema similar.
M Terry
El problema del OP fue que dividir un vector de caracteres con un salto de línea incluye el salto de línea en el vector de caracteres. Su respuesta solo es específica de la sintaxis
data.table
Como ejemplo de división de una línea de código en varias líneas
M Terry