Apa perbedaan antara require () dan library ()?

565

Apa perbedaan antara require()dan library()?

Marco
sumber
7
Menambahkan tautan ke posting blog @ Yihui kecuali dia ingin memposting versi itu sebagai jawaban. yihui.name/en/2014/07/library-vs-require
MichaelChirico
4
Meringkas posting blog @ Yihui: "Hadirin sekalian, saya sudah mengatakan ini sebelumnya: mengharuskan () adalah cara yang salah untuk memuat paket R; gunakan perpustakaan () sebagai gantinya"
De Novo
1
@DanHall ... karena library()segera gagal dengan keras, lebih awal, dan dengan pesan kesalahan yang relevan (jika paket tidak diinstal atau tidak dapat dimuat), sedangkan require()tidak menimbulkan kesalahan, diam-diam mengembalikan Boolean FALSE yang dibuang, dan menyebabkan kode gagal kemudian dan lebih samar dengan Error: object “bar” not foundpada (katakanlah) baris 175.
smci
1
@KonradRudolph: Selesai! Terima kasih atas tanggapan Anda.
Marco

Jawaban:

86

Selain saran bagus yang sudah diberikan, saya akan menambahkan ini:

Mungkin yang terbaik adalah menghindari penggunaan require() kecuali Anda benar-benar akan menggunakan nilai yang dikembalikannya misalnya dalam beberapa loop pemeriksaan kesalahan seperti yang diberikan oleh thierry.

Dalam kebanyakan kasus lain lebih baik digunakan library(), karena ini akan memberikan pesan kesalahan pada waktu pemuatan paket jika paket tidak tersedia. require()hanya akan gagal tanpa kesalahan jika paket tidak ada di sana. Ini adalah waktu terbaik untuk mengetahui apakah paket tersebut perlu diinstal (atau mungkin bahkan tidak ada karena salah eja). Mendapatkan umpan balik kesalahan lebih awal dan pada waktu yang relevan akan menghindari kemungkinan sakit kepala dengan melacak mengapa kode kemudian gagal ketika mencoba untuk menggunakan rutinitas perpustakaan

dww
sumber
356

Tidak banyak dalam pekerjaan sehari-hari.

Namun, menurut dokumentasi untuk kedua fungsi (diakses dengan meletakkan ?sebelum nama fungsi dan menekan enter), requiredigunakan di dalam fungsi, karena mengeluarkan peringatan dan melanjutkan jika paket tidak ditemukan, sedangkan libraryakan menimbulkan kesalahan.

richiemorrisroe
sumber
1
#richiemorrisroe: Terima kasih. Apakah ini berarti bahwa jika saya memuat paket yang saya butuhkan di awal kode-R saya, tidak masalah yang mana yang saya pilih?
Marco
6
selama Anda tidak memuat paket di dalam suatu fungsi, itu benar-benar tidak ada bedanya. Saya memuat semua paket saya menggunakan persyaratan, dan tidak tahu apa bedanya sampai saya membaca bantuan setelah melihat pertanyaan Anda.
richiemorrisroe
45
Alasan lain yang saya gunakan requireadalah itu membuat saya tidak menyebut paket sebagai libraries, sebuah praktik yang mendorong R-cognoscenti ke dinding. Ini libraryadalah lokasi direktori tempat paket berada.
IRTFM
22
Mereka memiliki perbedaan yang sangat relevan. Jangan gunakan require, kecuali Anda memeriksa nilai pengembalian (dan dalam kasus itu biasanya ada alternatif yang lebih baik, misalnya loadNamespace).
Konrad Rudolph
256

Manfaat lain require()adalah bahwa ia mengembalikan nilai logis secara default. TRUEjika paket dimuat, FALSEjika tidak.

> test <- library("abc")
Error in library("abc") : there is no package called 'abc'
> test
Error: object 'test' not found
> test <- require("abc")
Loading required package: abc
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,  :
  there is no package called 'abc'
> test
[1] FALSE

Jadi Anda dapat menggunakan require()konstruksi seperti di bawah ini. Yang terutama berguna jika Anda ingin mendistribusikan kode Anda ke instalasi R kami adalah paket mungkin tidak diinstal.

if(require("lme4")){
    print("lme4 is loaded correctly")
} else {
    print("trying to install lme4")
    install.packages("lme4")
    if(require(lme4)){
        print("lme4 installed and loaded")
    } else {
        stop("could not install lme4")
    }
}
Thierry
sumber
65

Anda dapat menggunakan require()jika Anda ingin menginstal paket jika dan hanya jika perlu, seperti:

if (!require(package, character.only=T, quietly=T)) {
    install.packages(package)
    library(package, character.only=T)
}

Untuk beberapa paket yang bisa Anda gunakan

for (package in c('<package1>', '<package2>')) {
    if (!require(package, character.only=T, quietly=T)) {
        install.packages(package)
        library(package, character.only=T)
    }
}

Kiat pro:

  • Saat digunakan di dalam skrip, Anda dapat menghindari layar dialog dengan menentukan reposparameter install.packages(), seperti

    install.packages(package, repos="http://cran.us.r-project.org")
  • Anda dapat membungkus require()dan library()masuk suppressPackageStartupMessages()ke, baik, menekan pesan startup paket, dan juga menggunakan parameter require(..., quietly=T, warn.conflicts=F)jika diperlukan untuk menjaga instalasi tetap diam.

Daniel Sparing
sumber
46

Selalu gunakan library. Tidak pernah 1 digunakan require.

( 1 Hampir tidak pernah. Mungkin .)

Singkatnya, ini karena, ketika menggunakan require, kode Anda mungkin menghasilkan hasil yang berbeda dan salah, tanpa menandakan kesalahan . Ini jarang tetapi tidak hipotetis! Pertimbangkan kode ini, yang menghasilkan hasil yang berbeda tergantung pada apakah {dplyr} dapat dimuat:

require(dplyr)

x = data.frame(y = seq(100))
y = 1
filter(x, y == 1)

Ini dapat menyebabkan hasil yang sedikit salah. Menggunakan libraryalih-alih requiremelempar kesalahan di sini, menandakan dengan jelas bahwa ada sesuatu yang salah. Ini bagus .

Itu juga membuat debug semua kegagalan lainnya lebih sulit: Jika Anda requiresebuah paket di awal skrip Anda dan menggunakan ekspornya di baris 500, Anda akan mendapatkan pesan kesalahan "objek 'foo' tidak ditemukan" di baris 500, daripada sebuah kesalahan "tidak ada paket yang disebut 'bla'".

Satu-satunya kasus penggunaan yang dapat diterima requireadalah ketika nilai pengembaliannya segera diperiksa, seperti yang ditunjukkan beberapa jawaban lainnya. Ini adalah pola yang cukup umum tetapi bahkan dalam kasus ini lebih baik (dan disarankan, lihat di bawah) untuk memisahkan pemeriksaan keberadaan dan pemuatan paket.

Lebih teknis, requiresebenarnya memanggil secara libraryinternal (jika paket belum terpasang - requiredengan demikian melakukan pemeriksaan berlebihan, karena library juga memeriksa apakah paket sudah dimuat). Berikut ini adalah implementasi yang disederhanakan requireuntuk menggambarkan apa yang dilakukannya:

require = function (package) {
    already_attached = paste('package:', package) %in% search()
    if (already_attached) return(TRUE)
    maybe_error = try(library(package, character.only = TRUE)) 
    success = ! inherits(maybe_error, 'try-error')
    if (! success) cat("Failed")
    success
}

Pengembang R yang berpengalaman setuju:

Yihui Xie , penulis {knitr}, {bookdown} dan banyak paket lainnya mengatakan :

Saudara-saudara, saya sudah mengatakan ini sebelumnya: mengharuskan () adalah cara yang salah untuk memuat paket R; gunakan perpustakaan () sebagai gantinya

Hadley Wickham , penulis paket R yang lebih populer daripada siapa pun, kata

Gunakan library(x)dalam skrip analisis data. [...] Anda tidak perlu menggunakan require()( requireNamespace()hampir selalu lebih baik)

Konrad Rudolph
sumber
Saya akan menunjuk persis sama, kecuali jika Anda memanggil SEMUA fungsi dengan sintaks class::function, gunakan library()untuk menghindari hal itu.
Ghost
19
?library

dan kamu akan lihat:

library(package)dan require(package)keduanya memuat paket dengan nama packagedan meletakkannya di daftar pencarian. requiredirancang untuk digunakan di dalam fungsi-fungsi lain; itu kembali FALSEdan memberikan peringatan (bukan kesalahan seperti yang library()dilakukan secara default) jika paket tidak ada. Kedua fungsi memeriksa dan memperbarui daftar paket yang saat ini dimuat dan tidak memuat ulang paket yang sudah dimuat. (Jika Anda ingin memuat ulang paket seperti itu, hubungi detach(unload = TRUE)atau unloadNamespacepertama.) Jika Anda ingin memuat paket tanpa meletakkannya di daftar pencarian, gunakan requireNamespace.

dwstu
sumber
9

Teori awal saya tentang perbedaannya adalah bahwa librarymemuat paket apakah sudah dimuat atau tidak, yaitu mungkin memuat ulang paket yang sudah dimuat, sementara requirehanya memeriksa apakah itu dimuat, atau memuatnya jika tidak (sehingga penggunaan dalam fungsi yang bergantung pada paket tertentu). Dokumentasi membantah ini, bagaimanapun, dan secara eksplisit menyatakan bahwa tidak ada fungsi akan memuat ulang paket yang sudah dimuat.

dsb
sumber
18
ini menarik, tetapi bukankah sebenarnya jawaban untuk pertanyaan ...?
Ben Bolker
3

Di sini tampaknya ada perbedaan pada paket yang sudah dimuat. Memang benar bahwa keduanya membutuhkan dan pustaka tidak memuat paket. Perpustakaan melakukan banyak hal lain sebelum memeriksa dan keluar.

Saya akan merekomendasikan menghapus "memerlukan" dari awal fungsi yang berjalan 2mil kali, tetapi jika, untuk beberapa alasan saya perlu menyimpannya. butuhkan secara teknis pemeriksaan lebih cepat.

microbenchmark(req = require(microbenchmark), lib = library(microbenchmark),times = 100000)
Unit: microseconds
 expr    min     lq      mean median     uq        max neval
  req  3.676  5.181  6.596968  5.655  6.177   9456.006 1e+05
  lib 17.192 19.887 27.302907 20.852 22.490 255665.881 1e+05
Bentuk
sumber
Saya berpendapat bahwa ini adalah alasan kuat untuk memperbaiki implementasi librarysebagai gantinya (kedua fungsi, seperti saat ini dikirim dengan R, adalah kekacauan besar).
Konrad Rudolph
@KonradRudolph, jika seseorang akan memperbaiki pustaka, mungkin mereka juga dapat mengaktifkan pemuatan berdasarkan versi secara eksplisit dan menjadikan lampiran sebagai opsi argumen
Shape
Ya, saya benar-benar setuju tetapi itu akan mengubah semantik, bukan hanya kinerja. Bagaimanapun, versi tidak akan pernah bekerja dengan paket di R, sayangnya. Saya sedang mengerjakan pengganti untuk ini (sungguh!). Sedangkan untuk melampirkan, Anda dapat menggunakan loadNamespace, yang memuat paket dan mengembalikan namespace-nya, tanpa melampirkannya.
Konrad Rudolph