Podziel kod na wiele wierszy w skrypcie języka R.

137

Chcę podzielić wiersz w skrypcie R na wiele wierszy (ponieważ jest za długi). W jaki sposób mogę to zrobić?

Konkretnie mam taką linię jak

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

Czy można podzielić długą ścieżkę na wiele linii? próbowałem

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

z returnkluczem na końcu pierwszej linii; ale to nie działa.

Dzięki.

Curious2learn
źródło

Odpowiedzi:

107

Nie łamiesz kodu w wielu wierszach, ale raczej w jednym identyfikatorze . Jest różnica.

W przypadku swojego problemu spróbuj

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

co również pokazuje, że dzielenie kodu w wielu wierszach jest całkowicie w porządku.

Dirk Eddelbuettel
źródło
13
Dzięki! Zastanawiałem się, czy istnieje znak, który mógłbym umieścić na końcu linii, aby wskazać R, że kod jest kontynuowany w następnej linii. Na przykład „\” w Pythonie. Jednak Twoje rozwiązanie działa dobrze w przypadku konkretnego problemu z kontynuacją ciągu.
Curious2learn
14
albo lepiej użyj paste0 (...), co jest równoważne wklejeniu (..., sep = "")
gkcn
31
Ale paste0jeszcze nie istniał, kiedy pisałem odpowiedź 2+ lata temu.
Dirk Eddelbuettel
Wygląda na to, że zmiana została odrzucona, a ja mniej więcej zgadzam się z odrzuceniem. Odpowiedź jest nadal poprawna, ma swój kontekst, a komentarze ją aktualizują.
Dirk Eddelbuettel
Dzięki za to. Zmyliłem się, że do dzielenia długich linii należy użyć plusa. Cieszę się, że rzeczywistość jest znacznie prostsza!
Iain Samuel McLean Starszy
143

Tak, komentarze są za małe. W każdym razie @Dirk ma rację.

R nie trzeba mówić, że kod zaczyna się w następnej linii. Jest mądrzejszy niż Python ;-) i po prostu będzie czytać następny wiersz, gdy uzna, że ​​instrukcja jest „nie zakończona”. Właściwie w twoim przypadku przeszedł również do następnej linii, ale R przyjmuje powrót jako znak, gdy jest umieszczony między "".

Pamiętaj, że musisz się upewnić, że kod nie jest skończony. Porównać

a <- 1 + 2
+ 3

z

a <- 1 + 2 +
3

Tak więc, rozkładając kod w wielu wierszach, musisz upewnić się, że R wie, że coś nadchodzi, albo przez:

  • pozostawienie otwartego nawiasu lub
  • zakończenie wiersza operatorem

Kiedy mówimy o strunach, to nadal działa, ale musisz być trochę ostrożny. Możesz otworzyć cudzysłowy, a R będzie czytać dalej, dopóki go nie zamkniesz. Ale każdy znak, w tym nowa linia, będzie postrzegany jako część ciągu:

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.

To jest powód, dla którego w tym przypadku twój kod nie działał: ścieżka nie może zawierać znaku nowego wiersza ( \n). Więc to też, dlaczego lepiej używać roztworu z paste()lub paste0()Dirk proponowane.

Joris Meys
źródło
Dzięki Joris. Widziałem przykłady podobne do tych, które podałeś w niektórych dokumentach online i wypróbowałem to również dla ciągu. Pomyślałem, że jeśli nie napotka cudzysłowu zamykającego, przejdzie do następnej linii. Ale ze stringiem to nie działa, a raczej, jak powiedziałeś, działa w inny sposób w tym sensie, że przyjmuje enter jako znak nowego wiersza.
Curious2learn
Dziękuję za wyjaśnienie, dlaczego czasami można podzielić linie za pomocą znaku plus!
Iain Samuel McLean Starszy
8
nie, tutaj nie jest mądrzejszy niż Python. zamiast paste("~one",\n"/two")po prostu potrzebujesz ("~one" \n "/two"). upuść przecinki i paste. Nie wyglądam na oszołomionego językiem. Używam obu języków, ale zawsze uważałem, że wklejanie jest irytujące.
Phil Cooper
2
@JorisMeys Racja, próbowałem poprawić to zniekształcenie. Użyj parenów i nie potrzebujesz znaku "\" do kontynuacji linii. Podoba mi się to, ponieważ możesz także komentować wiersze, których nie możesz zrobić za pomocą składni "\" (np. ("one"\n "/one.one" # some comment\n "/two")' Przykłady w stackoverflow.com/questions/10660435/ ...
Phil Cooper
1
leaving a bracket open, or ending the line with an operatorte dwa są drogą do zrobienia.
SIslam
35

Powyższa metoda Dirka absolutnie zadziała, ale jeśli szukasz sposobu na wprowadzenie długiego ciągu, w którym ważne jest zachowanie białych znaków / struktury (przykład: zapytanie SQL używające RODBC), istnieje dwuetapowe rozwiązanie.

1) Wprowadź ciąg tekstowy w wielu wierszach

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

2) R wprowadzi kilka \npostaci. Usuń te z strwrap(), które niszczy białe znaki, zgodnie z dokumentacją :

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

Mówiąc strwrap, aby zawijał twój tekst do bardzo, bardzo długiego wiersza, otrzymasz pojedynczy wektor znakowy bez białych znaków / znaków nowej linii.

Andrzej
źródło
3
Najbardziej podoba mi się ta odpowiedź, ponieważ nie muszę pisać tylu przecinków, co przy wklejaniu, jeśli ciąg jest dość długi. +1
user3032689
3
Należy pamiętać, że strwrapmoże zwrócić wektor wielu ciągów, nawet jeśli łańcuch źródłowy nie przekracza 10 tys. Znaków. Spróbuj strwrap("a\n\nb"). Zwróci wektor o długości 3 i musisz go wkleić z powrotem za paste(strwrap("a\n\nb"), collapse=" ")pomocą kleju do znaków spacji, aby zwinąć wektor.
Gedrox,
17

W tym konkretnym przypadku jest file.path:

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

Wiem, że ten post jest stary, ale miałem taką sytuację i chcę tylko podzielić się moim rozwiązaniem. Wszystkie powyższe odpowiedzi działają poprawnie. Ale jeśli masz kod, taki jak ten w składni łańcuchowej data.table, staje się on trudnym wyzwaniem. np. Miałem taki problem.

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

Wypróbowałem większość powyższych sugestii i nie zadziałały. ale doszedłem do wniosku, że można je podzielić po przecinku w środku []. Dzielenie ][nie działa.

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
źródło
Czy to możliwe, że pomyliłeś pytanie, na które próbowałeś odpowiedzieć? Nie ma to nic wspólnego z pytaniem OP.
zerweck
Ma. Głównym pytaniem jest, jak podzielić wiersz kodu na kilka wierszy. Pokazałem to na innym przykładzie, nieco bardziej złożonym niż pierwotne pytanie. Pomyślałem, że trzeba to opublikować, ponieważ spędziłem dużo czasu, próbując wymyślić, jak podzielić ten konkretny fragment kodu. I myślę, że pomoże to komuś z podobnym problemem.
M Terry
Problem OP polegał na tym, że rozdzielenie wektora znakowego z podziałem wiersza obejmuje podział wiersza w wektorze znakowym. Twoja odpowiedź dotyczy tylko składni
data.table
Jako przykład podzielenia linii kodu na wiele linii
M Terry