2013-05-17 9 views
5

5 dni i nadal nie ma odpowiedziBrakujące błąd podczas korzystania z obiektu (krok) w obrębie zdefiniowanych przez użytkownika funkcja

  • Jak widać po komentarzu Simona, to jest powtarzalne i bardzo dziwny problem. Wydaje się, że problem pojawia się tylko wtedy, gdy regresja krokowa z bardzo dużą mocą predykcyjną jest zawijana w funkcję.

Od pewnego czasu borykam się z tym problemem i każda pomoc będzie bardzo cenna. Próbuję napisać funkcję, która uruchamia kilka stopniowych regresji i wyświetla wszystkie z nich na liście. Jednak R ma problem z odczytaniem zestawu danych, który określam w argumentach funkcji. Znalazłem kilka podobnych błędów na różnych płytach (here, here i here), jednak żadna z nich nigdy nie została rozwiązana. Wszystko sprowadza się do kilku dziwnych problemów z wywołaniem funkcji step() w funkcji zdefiniowanej przez użytkownika. Korzystam z poniższego skryptu, aby przetestować mój kod. Uruchom cała rzecz kilka razy, aż pojawia się błąd (uwierzcie mi, to będzie):

test.df <- data.frame(a = sample(0:1, 100, rep = T), 
         b = as.factor(sample(0:5, 100, rep = T)), 
         c = runif(100, 0, 100), 
         d = rnorm(100, 50, 50)) 
test.df$b[10:100] <- test.df$a[10:100] #making sure that at least one of the variables has some predictive power 

stepModel <- function(modeling.formula, dataset, outfile = NULL) { 
    if (is.null(outfile) == FALSE){ 
    sink(file = outfile, 
     append = TRUE, type = "output") 
    print("") 
    print("Models run at:") 
    print(Sys.time()) 
    } 
    model.initial <- glm(modeling.formula, 
         family = binomial, 
         data = dataset) 
    model.stepwise1 <- step(model.initial, direction = "backward") 
    model.stepwise2 <- step(model.stepwise1, scope = ~.^2) 
    output <- list(modInitial = model.initial, modStep1 = model.stepwise1, modStep2 = model.stepwise2) 
    sink() 
    return(output) 
} 

blah <- stepModel(a~., dataset = test.df) 

ta zwraca następujący komunikat o błędzie (jeśli błąd nie pojawia się od razu, zachować ponowne uruchomienie test.df skrypt jak również wezwanie do stepModel(), pojawi się ona w końcu):

Error in is.data.frame(data) : object 'dataset' not found 

I ustalili, że wszystko działa dobrze aż model.stepwise2 zaczyna się zbudowany. W jakiś sposób, tymczasowy obiekt "dataset" działa dobrze dla pierwszej regresji krokowej, ale nie jest rozpoznawany przez drugi. Znalazłem to, komentując część funkcji, jak widać poniżej. Kod ten będzie działał dobrze, udowadniając, że obiekt „zbiór danych” została pierwotnie są rozpoznawane:

stepModel1 <- function(modeling.formula, dataset, outfile = NULL) { 
    if (is.null(outfile) == FALSE){ 
    sink(file = outfile, 
     append = TRUE, type = "output") 
    print("") 
    print("Models run at:") 
    print(Sys.time()) 
    } 
    model.initial <- glm(modeling.formula, 
         family = binomial, 
         data = dataset) 
    model.stepwise1 <- step(model.initial, direction = "backward") 
# model.stepwise2 <- step(model.stepwise1, scope = ~.^2) 
# sink() 
# output <- list(modInitial = model.initial, modStep1 = model.stepwise1, modStep2 = model.stepwise2) 
    return(model.stepwise1) 
} 

blah1 <- stepModel1(a~., dataset = test.df) 

EDIT - zanim ktoś pyta, funkcje wszystko podsumowanie() tam, ponieważ pełna funkcja (i edytować go tak że możesz skupić się na błędzie) ma inny element, który definiuje plik, do którego możesz wyprowadzać krok po kroku. Właśnie pozbył nich

EDIT 2 - Sesja informacji

sessionInfo() R w wersji 2.15.1 (2012-06-22) Platforma: PC-x86_64-mingw32/64 (64-bitowy)

locale: 
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C       
[5] LC_TIME=English_United States.1252  

attached base packages: 
[1] tcltk  stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] sqldf_0.4-6.4   RSQLite.extfuns_0.0.1 RSQLite_0.11.3  chron_2.3-43   
[5] gsubfn_0.6-5   proto_0.3-10   DBI_0.2-6    ggplot2_0.9.3.1  
[9] caret_5.15-61   reshape2_1.2.2  lattice_0.20-6  foreach_1.4.0   
[13] cluster_1.14.2  plyr_1.8    

loaded via a namespace (and not attached): 
[1] codetools_0.2-8 colorspace_1.2-1 dichromat_2.0-0 digest_0.6.2  grid_2.15.1  
[6] gtable_0.1.2  iterators_1.0.6 labeling_0.1  MASS_7.3-18  munsell_0.4  
[11] RColorBrewer_1.0-5 scales_0.2.3  stringr_0.6.2  tools_2.15 

Edycja 3 - ten wykonuje te same czynności, jak w funkcji, po prostu nie używając funkcji. Będzie to działać dobrze za każdym razem, nawet gdy algorytm nie zbiegają:

modeling.formula <- a~. 
dataset <- test.df 
outfile <- NULL 
if (is.null(outfile) == FALSE){ 
    sink(file = outfile, 
     append = TRUE, type = "output") 
    print("") 
    print("Models run at:") 
    print(Sys.time()) 
} 
    model.initial <- glm(modeling.formula, 
         family = binomial, 
         data = dataset) 
    model.stepwise1 <- step(model.initial, direction = "backward") 
    model.stepwise2 <- step(model.stepwise1, scope = ~.^2) 
    output <- list(modInitial = model.initial, modStep1 = model.stepwise1, modStep2 = model.stepwise2) 
+0

Próbowałem odtworzyć ten błąd i nie mogłem tego zrobić. Używam wersji 2.15.3 64-bitowej na Windows 7, a funkcja działa poprawnie, dopóki nie osiągnie połączenia z 'sink()', w którym to momencie zgłosiło 'In sink(): no sink to remove'. Czy możesz powiedzieć, jakiej wersji R używasz? – Simon

+0

@Simon - właśnie wstawiłem argument wyjściowy do mojej funkcji. to spowodowało, że błąd pojawił się ponownie u mnie. Dodaję teraz informacje o systemie i sesji do pytania. – zap2008

+0

To jest bardzo dziwne ... Błąd pojawia się pozornie przypadkowo. Jeśli uruchomię mój kod 10 razy, wyskoczy to może dwa razy ... – zap2008

Odpowiedz

4

Korzystanie do.call odnieść się do danych zawartych w środowisku wywołującym pracuje dla mnie. Aby uzyskać oryginalną sugestię, patrz https://stackoverflow.com/a/7668846/210673. Oto wersja, która działa (z usuniętym kodem sink).

stepModel2 <- function(modeling.formula, dataset) { 
    model.initial <- do.call("glm", list(modeling.formula, 
         family = "binomial", 
         data = as.name(dataset))) 
    model.stepwise1 <- step(model.initial, direction = "backward") 
    model.stepwise2 <- step(model.stepwise1, scope = ~.^2) 
    list(modInitial = model.initial, modStep1 = model.stepwise1, modStep2 = model.stepwise2) 
} 

blah <- stepModel2(a~., dataset = "test.df") 

Zawodzi niezmiennie z set.seed(6) z oryginalnym kodem.Przyczyną niepowodzenia jest to, że zmienna dataset nie jest obecna w funkcji step i chociaż nie jest potrzebna przy tworzeniu model.stepwise1, jest potrzebna dla model.stepwise2, gdy model.stepwise1 zachowuje liniowy termin. Tak jest w przypadku, gdy twoja wersja zawodzi. Wywołanie zestawu danych ze środowiska globalnego, tak jak to robię, rozwiązuje ten problem.

+0

więc sugerujesz, że zdefiniowałem obiekt o nazwie 'dataset' w środowisku globalnym? To było moje obejście, ale czyni to funkcję mniej użyteczną. – zap2008

+0

Nie, ta funkcja odwołuje się do "test.df" w oryginalnym środowisku, a nie do "zestawu danych" w funkcji. Mój tekst na ten temat jest prawdopodobnie niejasny; Będę edytować. Powinieneś być w stanie załadować tę funkcję i uruchomić przykład kodu na dole. – Aaron

+0

To świetnie, dziękuję bardzo! Próbowałem użyć 'do.call' zanim jeszcze to opublikowałem, jak sugerowano w połączonym pytaniu, ale próbowałem użyć' get() 'zamiast' as.name() '. Czym różnią się te dwie? – zap2008

Powiązane problemy