2016-01-29 9 views
19

Chcę ustawić bieżącą lokalizację pliku jako katalog roboczy.Jak ustawić aktualną lokalizację pliku jako domyślny katalog roboczy w programowaniu R?

Korzystanie Rstudio (działa!):

# Author : Bhishan Poudel 
# Program : writehere.r 
# Source : Rscript writehere.r 

# set working directory here 
this.dir <- dirname(parent.frame(2)$ofile) # frame(3) also works. 
setwd(this.dir) 

# Sample data to test this code 
mydata <- seq(1:10) 
write.csv(mydata,"writehere.dat") 
#This works flawlessly in MacOS 10.9 and Ubuntu 15.1. 

pomocą polecenia z terminala: Rscript writehere.r (! Nie działa)

Error in dirname(parent.frame(2)$ofile) : 
    a character vector argument expected 
Execution halted 


------------------ 
(program exited with code: 1) 

pomocą polecenia z terminala: Rscript writehere.r (Działa teraz!)

# Author : Bhishan Poudel 
# Program : writehere.r 
# Source : Rscript example.r 

# set working directory here 
this_dir <- function(directory) 
setwd(file.path(getwd(), directory)) 

# Sample data to test this code 
mydata <- seq(1:10) 
write.csv(mydata,"writehere.dat") 

Korzystanie z funkcji wewnątrz ~/.Rprofile dla Rstudio (działa!):,

############################################## 
# inside ~/.Rprofile 
# set up working directory 
setwd_thisdir <- function() { 
    this.dir <- dirname(parent.frame(3)$ofile) 
    setwd(this.dir) 
} 
############################################## 

Następnie w dowolnym katalogu powiedzmy mam writehere.r pliku, teraz działa.

# Author : Bhishan Poudel 
# Program : writehere.r 
# Compile : Rscript writehere.r 

# set working directory here 
setwd_thisdir 

# Sample data to test this code 
mydata <- seq(1:10) 
write.csv(mydata,"writehere.dat") 

Pytanie: Dlaczego funkcja

this.dir <- dirname(parent.frame(2)$ofile) # frame(3) also works. 
setwd(this.dir) 

nie działa dla edytorów tekstowych innych niż Rstudio?

kilka przydatnych linków są następujące:
R setting working directory to source file location?
R command for setting working directory to source file location
get filename and path of `source`d file
setwd() in the current working dir
Command for "Set working directory to source file location"
SublimeText and R: Setting Current File Directory
Setting working directory through a function
What is a fool-proof way of permanently setting R working directory?
R setting working directory to source file location?
How to get into the directory of a file in R?

+0

co to jest "class (parent.frame (2) $ ofile)"? – MichaelChirico

+0

@MichaelChirico Nie wiem, skorzystałem z sugestii z linku http://stackoverflow.com/questions/34843889/r-setting-working-to-source-file-location –

+0

dodaj wiersz 'print (class (parent.frame (2) $ ofile)) 'i spróbuj uruchomić twoją funkcję.l – MichaelChirico

Odpowiedz

1

AKTUALIZACJA: Zdałem sobie sprawę, że ta odpowiedź w ogóle nie pomogła, a ja opublikuję kolejny, który rozwiązuje problem.

O ile kod, który chcesz uruchomić, nie wymaga żadnych dodatkowych argumentów, rozwiązanie przedstawione na poniższym rysunku, przy użyciu eval(expr, envir), może wystarczyć.

Rozważmy następujący przykład przy użyciu print(environment()), który powinien zwrócić environment: R_GlobalEnv, gdy jest używany w wierszu poleceń.Funkcja test_1 będzie drukować informacje o środowisku wewnętrznym, które jest tworzone podczas wywoływania funkcji, podczas gdy funkcja test_2 zwróci pożądany wynik.

test_1 <- function(){ 
    print(environment()) 
} 

test_2 <- function(){ 
    .expr <- quote({ 
     print(environment()) 
     }) 
    .envir <- sys.frame(which = -1) 
    eval(expr = .expr, 
     envir = .envir) 
} 

sys.frame(which = -1) sprawia, że ​​ekspresja jest oceniana w warunkach, w których wywoływana jest funkcja. Jeśli masz pewność, że zawsze chcesz korzystać ze środowiska globalnego, lepiej użyć .GlobalEnv. Ważne jest również cytowanie wyrażenia, którego chcesz użyć, w przeciwnym razie może nie działać zgodnie z oczekiwaniami.

Przyjemną cechą tego rozwiązania jest to, że nie trzeba modyfikować kodu, który chcesz wstawić do funkcji, po prostu zacytuj.

Wreszcie: Możliwe jest rozszerzenie tego podejścia tak, że twoja funkcja może przyjmować argumenty, które następnie zostaną podane do kodu, który chcesz ocenić w innym środowisku. Będzie to jednak wymagało nieco nietrywialnego podkręcania wyrażenia, które chcesz ocenić; może być konieczne użycie konstrukcji bquote + .() - a ponadto może być konieczne użycie call i do.call.

1

Pierwsza odpowiedź, którą zupełnie pominąłem, ponieważ nie miałem uważnie przyjrzałem się temu, co chciałeś osiągnąć. Przedstawione tutaj rozwiązanie powinno jednak wystarczyć.

Pierwsza uwaga, że ​​source ma argument chdir, który w pliku pomocy jest opisany za pomocą: logical; jeśli TRUE i file jest nazwą ścieżki, katalog roboczy R zostaje tymczasowo zmieniony na katalog zawierający file do oceny.

Aby ręcznie określić, że argument za każdym razem, gdy chcesz pozyskać plik byłby ból, więc dodajmy coś .Rprofile który zmienia wartość domyślną chdir z FALSE do TRUE.

formals -function mogą być wykorzystywane do modyfikowania domyślną wartość , ale kiedy jest stosowany na funkcję, która należy do innej środowiska, wynik będzie taki, że lokalna kopia tej funkcji zostanie utworzone zamiast. To nie jest wystarczająco dobre.

To prawdopodobnie kilka sposobów, aby rozwiązać ten problem, ale następujący po nim mały hak source zrobił mi tę sztuczkę, kiedy wstawiłem ją do .Rprofile.

.temporary_copy_source <- base::source 
formals(.temporary_copy_source)$chdir <- TRUE 
utils::assignInNamespace(
    x = "source", 
    value = .temporary_copy_source, 
    ns = environment(source)) 
rm(.temporary_copy_source) 

Słowo ostrzeżenia: Metoda przedstawiona tutaj może w zasadzie pozwalają użytkownikom na modyfikowanie domyślnych wartości jakiegokolwiek argumentu w jakiejkolwiek funkcji, ale to byłoby to wyjątkowo zły pomysł, aby zrobić. Zachowaj , pamiętając, że twoje skrypty mogą być później udostępnione komuś , które nie ma tego samego profilu .Rp, który masz. Nigdy nie pisz kodu , który wymaga takich modyfikacji przestrzeni nazw!

Powiązane problemy