Diviser le code sur plusieurs lignes dans un script R

137

Je veux diviser une ligne dans un script R sur plusieurs lignes (car elle est trop longue). Comment je fais ça?

Plus précisément, j'ai une ligne telle que

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

Est-il possible de diviser le long chemin sur plusieurs lignes? j'ai essayé

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

avec returnclé à la fin de la première ligne; mais cela ne fonctionne pas.

Merci.

Curieux2learn
la source

Réponses:

108

Vous ne cassez pas le code sur plusieurs lignes, mais plutôt sur un seul identifiant . Il existe une différence.

Pour votre problème, essayez

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

ce qui illustre également qu'il est parfaitement correct de casser le code sur plusieurs lignes.

Dirk Eddelbuettel
la source
13
Merci! Je me demandais s'il y avait un caractère que je pourrais mettre en fin de ligne pour indiquer à R que le code continue sur la ligne suivante. Tels que "\" en Python. Cependant, votre solution fonctionne bien pour le problème spécifique de la continuation de chaîne.
Curious2learn le
14
ou vous feriez mieux d'utiliser paste0 (...) qui équivaut à paste (..., sep = "")
gkcn
31
Mais paste0n'existait pas encore lorsque j'ai écrit la réponse il y a plus de 2 ans.
Dirk Eddelbuettel
Il semble que la modification a été rejetée et je suis plus ou moins d'accord avec le rejet. La réponse est toujours correcte, a son contexte et les commentaires la mettent à jour.
Dirk Eddelbuettel
Merci pour cela. J'ai appris à tort que vous deviez utiliser un plus pour séparer les longues lignes. Je suis content que la réalité soit beaucoup plus simple!
Iain Samuel McLean Elder
144

Bah, les commentaires sont trop petits. Quoi qu'il en soit, @Dirk a tout à fait raison.

R n'a pas besoin d'être informé que le code commence à la ligne suivante. Il est plus intelligent que Python ;-) et continuera simplement à lire la ligne suivante chaque fois qu'il considérera l'instruction comme "non terminée". En fait, dans votre cas, il est également passé à la ligne suivante, mais R prend le retour comme un caractère lorsqu'il est placé entre "".

Attention, vous devrez vous assurer que votre code n'est pas terminé. Comparer

a <- 1 + 2
+ 3

avec

a <- 1 + 2 +
3

Ainsi, lors de la diffusion de code sur plusieurs lignes, vous devez vous assurer que R sait que quelque chose arrive, soit en:

  • en laissant un support ouvert, ou
  • terminer la ligne avec un opérateur

Lorsque nous parlons de chaînes, cela fonctionne toujours, mais vous devez être un peu prudent. Vous pouvez ouvrir les guillemets et R lira jusqu'à ce que vous le fermiez. Mais chaque caractère, y compris la nouvelle ligne, sera vu comme faisant partie de la chaîne:

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.

C'est la raison pour laquelle dans ce cas, votre code n'a pas fonctionné: un chemin ne peut pas contenir de caractère de nouvelle ligne ( \n). C'est aussi pourquoi il vaut mieux utiliser la solution avec paste()ou paste0()Dirk proposée.

Joris Meys
la source
Merci Joris. J'ai vu des exemples similaires à ceux que vous avez donnés dans la documentation en ligne et j'ai essayé cela pour la chaîne aussi. Je pensais que s'il ne rencontrait pas de guillemet de clôture, il passerait à la ligne suivante. Mais avec une chaîne, cela ne fonctionne pas, ou plutôt, comme vous l'avez dit, fonctionne d'une manière différente dans le sens où il faut entrer comme caractère de nouvelle ligne.
Curious2learn le
Merci d'avoir expliqué pourquoi vous pouvez parfois diviser les lignes avec un signe plus!
Iain Samuel McLean Elder
8
non, ce n'est pas plus intelligent que python ici. plutôt que ce dont paste("~one",\n"/two")vous avez juste besoin ("~one" \n "/two"). laissez tomber les virgules et le paste. Je ne cherche pas la langue. J'utilise les deux langues mais j'ai toujours pensé que la pâte était une gêne.
Phil Cooper
2
@JorisMeys D'accord, j'essayais de corriger cette inexactitude. Utilisez des parenthèses et vous n'avez pas besoin du "\" pour la suite de la ligne. Je l'aime parce que vous pouvez aussi avoir des commentaires sur les lignes que vous ne pouvez pas faire avec la syntaxe "\" (exemple: ("one"\n "/one.one" # some comment\n "/two")' exemples dans stackoverflow.com/questions/10660435/…
Phil Cooper
1
leaving a bracket open, or ending the line with an operatorces deux sont la voie à suivre.
SIslam
35

La méthode de Dirk ci-dessus fonctionnera absolument, mais si vous cherchez un moyen d'apporter une longue chaîne où les espaces / la structure sont importants à préserver (exemple: une requête SQL utilisant RODBC), il existe une solution en deux étapes.

1) Amenez la chaîne de texte sur plusieurs lignes

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

2) R introduira un tas de \npersonnages. Supprimez-les avec strwrap(), ce qui détruit les espaces, conformément à la documentation :

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

En disant à strwrap d'encapsuler votre texte sur une très, très longue ligne, vous obtenez un vecteur de caractère unique sans espaces / caractères de nouvelle ligne.

Andrew
la source
3
J'aime plus cette réponse parce que je n'ai pas à écrire autant de virgules qu'avec coller, si la chaîne est assez longue. +1
user3032689
3
Sachez que cela strwrappeut renvoyer un vecteur de plusieurs chaînes même si la chaîne source ne dépasse pas 10 000 caractères. Essayez strwrap("a\n\nb"). Il renverra un vecteur de longueur 3 et vous devez le recoller en paste(strwrap("a\n\nb"), collapse=" ")utilisant une colle de caractère espace pour réduire le vecteur.
Gedrox
18

Pour ce cas particulier, il y a file.path:

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

Je sais que cet article est ancien, mais j'ai eu une situation comme celle-ci et je veux juste partager ma solution. Toutes les réponses ci-dessus fonctionnent bien. Mais si vous avez un code comme ceux de la syntaxe de chaînage data.table, cela devient un peu difficile. par exemple, j'ai eu un problème comme celui-ci.

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

J'ai essayé la plupart des suggestions ci-dessus et elles n'ont pas fonctionné. mais j'ai compris qu'ils pouvaient être séparés après la virgule à l'intérieur []. Le fractionnement ][ne fonctionne pas.

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
la source
Serait-ce que vous avez mélangé la question à laquelle vous tentiez de répondre? Cela n'a rien à voir avec la question d'OP.
zerweck
C'est vrai. La question principale est de savoir comment diviser une ligne de code en plusieurs lignes. J'ai démontré cela en utilisant un autre exemple qui est un peu plus complexe que la question initiale. J'ai pensé qu'il était nécessaire de le publier car j'ai passé beaucoup de temps à essayer de comprendre comment diviser ce morceau de code en particulier. Et je suppose que cela aide quelqu'un avec un problème similaire.
M Terry
Le problème de l'OP était que le fractionnement d'un vecteur de caractères avec un saut de ligne inclut le saut de ligne dans le vecteur de caractères. Votre réponse n'est spécifique qu'à la syntaxe
data.table
Comme exemple de division d'une ligne de code sur plusieurs lignes
M Terry