Bir R Hata Mesajını Okumak
Bir R hatasının iki parçası vardır ve ikisi de yararlıdır:
Error in "10" + 5 : non-numeric argument to binary operator
Error in ifadesinden sonra çağrı gelir - başarısız olan tam kod parçası ("10" + 5). İki noktadan sonra koşul gelir - neyin ters gittiği (non-numeric argument to binary operator). Önce çağrıyı okuyun: size nerede olduğunu söyler ve çoğu zaman sorunu alıntılanan kodda hemen orada görebilirsiniz. Sonra neden için koşulu okuyun.
Hızlı hata ayıklayanları acı çekenlerden iki alışkanlık ayırır. Birincisi, mesajı gerçekten okuyun - R'nin mesajları genellikle kesindir, yalnızca kısa ifade edilmiştir. İkincisi, sonuncuyu değil ilk hatayı ayıklayın: bir betiğin başındaki tek bir arıza, orijinali düzelttiğinizde hepsi kaybolan bir yığın aşağı akış "object not found" hatasına dönüşür. Bu sayfanın kalanı, en çok karşılaşacağınız mesajlar için bir çözücü ve ardından okumanın yetmediği durumlar için araçlardır.
İsim Hataları: Bulunamadı
Error: object 'total' not found - R bildiği her ortamı taradı ve hiçbir değişkenin adı bu değil. Neredeyse her durumu üç neden kapsar:
- Bir yazım hatası, büyük/küçük harf dahil. R büyük/küçük harfe duyarlıdır:
Total,totalveTOTALüç farklı isimdir ve R hangisini kastettiğinizi tahmin etmez. - Tanımlayan satır çalıştırılmadı. Betikte
total <- sum(x)yazdınız ama bu oturumda hiç yürütmediniz - R yeniden başlatıldıktan sonra sık görülür; betik dosyası satırı hâlâ gösterirken oturum onu hiç görmemiştir. Betiği en baştan çalıştırın. - Yanlış ortam. Bir fonksiyonun içinde oluşturulan değişkenler o çağrının içinde yaşar ve ölür. Birini fonksiyonun dışında kullanmak, artık var olmayan bir şeyi istemektir - bunun yerine değeri döndürün.
Error: could not find function "read_excel" - aynı fikir, ama bir fonksiyon adı için. On seferin dokuzunda fonksiyon, kurduğunuz ama bu oturumda yüklemediğiniz bir pakette bulunur:
library(readxl) # the fix: loading is per-session, installing is per-machine
df <- read_excel("data.xlsx")
library(readxl) çağrısının kendisi hata veriyorsa paket kurulu değildir - önce install.packages("readxl"). Ve fonksiyon temel R'ye aitse yanlış yazmışsınızdır (lenght() herkesin erginlenme törenidir).
Söz Dizimi Hataları: unexpected symbol
Error: unexpected symbol in "..." (ve kuzenleri unexpected ')', unexpected string constant), R'nin kodu ayrıştıramadığı bile anlamına gelir. Mesaj, R'nin fark ettiği yeri gösterir ve bu genellikle asıl hatanın ötesindedir. Alışıldık şüpheliler:
mean(x na.rm = TRUE) # missing comma - should be mean(x, na.rm = TRUE)
name <- "Ada # unclosed quote - swallows the following lines
total <- sum(c(1, 2, 3) # unclosed paren - the error fires lines later
İşaretlenen satır masum göründüğünde hata neredeyse her zaman onun üstündedir: dosyanın önceki bir yerinde kapatılmamış bir tırnak, parantez ya da süslü parantez. Eşleşen çiftleri vurgulayan bir kod düzenleyicisi bunları saniyeler içinde bulur.
Tür ve İndeksleme Hataları, Çözülmüş
non-numeric argument to binary operator - sayı olmayan bir şeyle matematik yaptınız, genellikle metin olarak gelmiş bir sayıyla (klasik kaynak içe aktarımlardır - veri türleri sayfasında ele alındığı gibi, başıboş tek bir sözcük içeren bir sütun character olarak gelir). Bozuk sürüm:
x <- "10"
x + 5
# Error in x + 5 : non-numeric argument to binary operator
Ve çözüm - önce dönüştürün, sonra hesaplayın:
subscript out of bounds - [[ ]] ile, n elemandan azı olan bir şeyde n konumunu istediniz:
scores <- list(ada = 92, grace = 88)
scores[[3]]
# Error in scores[[3]] : subscript out of bounds
İndekslemeden önce length() kontrol edin ya da daha iyisi isimle sorun (scores[["grace"]]); böylece yeniden sıralama sizi bozamaz. Asimetriye dikkat: tek köşeli parantezler daha bağışlayıcıdır - bir vektörde aralık dışı [ ], hata vermek yerine sessizce NA döndürür ve bu, gürültülü bir hatayı sessiz bir hatayla takas eder.
$ operator is invalid for atomic vectors - $, listelere ve veri çerçevelerine aittir. İsimli bir vektörde köşeli parantez kullanın:
([[ ]] yalın değeri verir; [ ] ismi iliştirilmiş tutar.) Bu hata çoğu zaman yukarı akıştaki bir şeyin, veri çerçevesi beklediğiniz yerde bir vektör döndürdüğü anlamına gelir - operatörü değiştirmek yerine gidip o varsayımı kontrol edin.
argument is of length zero - bir if (), içinde hiçbir şey olmayan bir koşul aldı; neredeyse her zaman eksik bir liste elemanından ya da hiçbir şey döndürmeyen bir fonksiyondan sızmış bir NULL:
threshold <- NULL
if (threshold > 5) print("big")
# Error in if (threshold > 5) print("big") : argument is of length zero
Kontrolü koruyun - ve && işlecinin yanıt bilinir bilinmez değerlendirmeyi durdurduğuna, dolayısıyla karşılaştırmanın bir NULL üzerinde hiç çalışmadığına dikkat edin:
(İlgili bir hata olan missing value where TRUE/FALSE needed, NULL yerine NA ile aynı arızadır - oradaki koruma eksik değerler sayfasında ele alınan is.na() fonksiyonudur.)
replacement has length zero - aynı hastalığın atama sürümü: x[2] <- numeric(0), tek bir yuvayı sıfır değerle doldurmaya çalışır. Sağ tarafı üreten şey boş geldi; atamayı değil onu ayıklayın.
Uyarılar Hata Değildir - Tehlike Tam da Budur
Bir hata yürütmeyi durdurur; bir uyarı durdurmaz. R hesabı bitirir, size bir sonuç verir ve çekincelerini sonradan söyler. O sonuç bazen sorunsuz, bazen sessizce yanlıştır:
İki satır da tamamlanır. Birincisi kısa vektörü geri dönüştürür ve longer object length is not a multiple of shorter object length uyarısı verir - 2 uzunluğundaki bir vektörü 3 uzunluğuna karşı geri dönüştürmek neredeyse hiç kimsenin kastettiği şey değildir. İkincisi NAs introduced by coercion uyarısı verir ve içinde bir delik olan, aşağı akıştaki her mean() çağrısının NA döndürmesine yol açacak bir vektör teslim eder. Her iki uyarıyı da kaydırıp geçilecek gürültü değil, araştırılacak hatalar olarak görün. Betiklerde bu duruşu options(warn = 2) ile zorunlu kılabilirsiniz; bu, her uyarıyı hataya yükseltir ve hiçbir şeyin sızmasına izin vermez.
tryCatch() ile Arızaları Ele Almak
Bazen bir hata beklenendir - yüzlerce dosyalık bir klasördeki tek bozuk dosya, tek bozuk satır - ve ölmek yerine onu ele alıp devam etmek istersiniz. tryCatch(), riskli bir ifadeyi işleyicilerle sarar:
Mekanizma: ana blok başarılı olursa değeri sonuçtur. Hata verirse bunun yerine error = işleyicisi çalışır ve onun dönüş değeri (burada NA) sonuç olur - betik devam eder. conditionMessage(e), günlüğe kaydetmek için orijinal mesajı geri kazanır. finally = her durumda çalışır, başarı da olsa başarısızlık da; bağlantı kapatma gibi temizlik işleri buraya aittir - yukarıda her sonuçtan önce yazdırdığını görebilirsiniz.
Bir de warning = işleyicisi vardır - tryCatch(as.numeric(x), warning = function(w) NA), bir önceki bölümdeki zorlama uyarısını geçiştirmek yerine yakalar. Bir uyarı: hiçbir şey günlüğe kaydetmeden yedek değer döndüren bir işleyici, arızaları ele almanın değil gizlemenin bir yoludur. Her zaman conditionMessage() kaydedin - gelecekteki sizin ona ihtiyacı olacak.
Arızayı Konumlandırmak: traceback(), browser() ve Dürüst Yazdırma
Hata iç içe fonksiyon çağrılarının derinlerinden geldiğinde mesaj tek başına sizi oraya hangi çağrı zincirinin götürdüğünü söylemez. Hatanın hemen ardından traceback() çalıştırın:
f <- function(x) g(x)
g <- function(x) stop("boom")
f(1)
# Error in g(x) : boom
traceback()
# 2: g(x)
# 1: f(1)
Arıza anındaki çağrı yığınını yazdırır - bir ucunda sizin çağrınız, diğer ucunda başarısız olan çağrı. Çalıştıracağınız bir sonraki şey olmalıdır; başka bir hata olduğunda yığın atılır.
Canlı bir bakış için browser(), onu yerleştirdiğiniz yerde yürütmeyi duraklatır ve sizi fonksiyonun içindeki etkileşimli bir isteme bırakır - değişkenleri inceleyin, n ile adımlayın, c ile devam edin, Q ile çıkın. debug(f) aynısını kod düzenlemeden yapar: f fonksiyonunu işaretler ve bir sonraki çağrısı tarayıcıda açılır (undebug(f) ile geri alın).
Bir de kimsenin konferans slaytlarına koymadığı ama herkesin kullandığı teknik var: yazdırma. Kontrol noktalarına print() ya da cat() serpin, çalıştırın ve gerçekliğin beklentilerinizle örtüşmeyi nerede bıraktığını görün. Meşrudur, hızlıdır ve betiklerde çoğu zaman en pratik araçtır. En iyi dostu, muhtemelen tüm R hatalarının yarısının arkasındaki soruyu - "bu nesne aslında nedir?" - yanıtlayan str() fonksiyonudur:
Tek ve derli toplu bir okuma: bu bir liste, iki eleman, biri bir integer vektör, diğeri şu sütun ve türlere sahip bir veri çerçevesi. Bir $ başarısız olduğunda ya da matematik yaramazlık yaptığında, kuram üretmeden önce nesneye str() uygulayın - yanıt genellikle tam oradadır ("...ah, bu, veri çerçevemi içeren 1 uzunluğunda bir listeymiş").
Buradan Ne Çıkarıyorsunuz
- Mesajı okuyun:
Error insonrası nerede olduğunu, iki nokta sonrası nedenini söyler. En gürültülüyü değil ilk hatayı düzeltin. object not found= yazım hatası, henüz çalıştırılmamış kod ya da yalnızca bir fonksiyonun içinde var olmuş bir değişken.could not find function= neredeyse her zaman eksik birlibrary()çağrısı.unexpected symbol, ayrıştırılamayan dilbilgisi demektir - ve asıl hata çoğu zaman işaretlenen noktadan önceki kapatılmamış bir tırnak ya da parantezdir.- Tür/indeks klasikleri -
non-numeric argument,subscript out of bounds, atomik vektörlerde$,argument is of length zero- her biri bir nesnenin ne olduğuna dair yanlış bir varsayıma işaret eder;str()bu varsayımı tek çağrıda kontrol eder. - Uyarılar yürütmeyi durdurmaz; tam da bu yüzden dikkati hak ederler - sonuç sessizce yanlış olabilir.
tryCatch(error =, warning =, finally =), beklenen arızaları ölmeden ele alır (her zamanconditionMessage()kaydedin); bir hatanın hemen ardındantraceback()çağrı zincirini gösterir;browser()/debug()içeride duraklatır;print()ile hata ayıklamak dürüst bir iştir.
Sırada: aslında hata olmayan birçok "hata" üç karakterlik tek bir değere dayanır - NA ve eksik değerlerin R'nin hesapladığı her şeyin içinden nasıl aktığı.
Sıkça Sorulan Sorular
R'de "object 'x' not found" ne demektir?
R, x adında bir değişken aradı ve taradığı hiçbir ortamda böyle bir isim yok. Olasılık sırasına göre nedenler: isimde bir yazım hatası (R büyük/küçük harfe duyarlıdır - Total, total değildir), x değişkenini oluşturan satır bu oturumda henüz çalıştırılmadı ya da x bir fonksiyonun içinde oluşturuldu ve siz onu dışarıda kullanmaya çalışıyorsunuz.
R'de "could not find function" ne demektir?
Fonksiyon, bu oturumda yüklemediğiniz bir pakette bulunuyor. Bir paketi kurmak makine başına bir kezdir; library() ise oturum başına bir kezdir ve library() çağrısını unutmak alışıldık nedendir. library() çağrısının kendisi başarısız oluyorsa paket kurulu değildir. Fonksiyon adındaki bir yazım hatası da aynı hatayı üretir.
R'de tryCatch ile hatalar nasıl ele alınır?
Riskli ifadeyi sarın: tryCatch(expr, error = function(e) fallback, warning = function(w) fallback, finally = cleanup). expr başarısız olursa betik ölmek yerine eşleşen işleyici çalışır ve işleyicinin döndürdüğü şey sonuç olur. Bir işleyicinin içindeki conditionMessage(e), günlüğe kaydetmeniz için orijinal mesajı verir.
R'de traceback() ne yapar?
Bir hatanın hemen ardından çalıştırıldığında traceback(), hata tetiklendiğinde etkin olan fonksiyon çağrıları zincirini yazdırır - bir ucunda sizin çağrınız, diğer ucunda başarısız olan çağrı. Hiçbir şeyi düzeltmez; nereye bakacağınızı söyler ve hata iç içe fonksiyonların derinlerinden geldiğinde savaşın büyük kısmı budur.