Masih mencoba masuk ke logika R ... apa cara "terbaik" untuk membongkar (pada LHS) hasil dari fungsi yang mengembalikan beberapa nilai?
Rupanya saya tidak bisa melakukan ini:
R> functionReturningTwoValues <- function() { return(c(1, 2)) }
R> functionReturningTwoValues()
[1] 1 2
R> a, b <- functionReturningTwoValues()
Error: unexpected ',' in "a,"
R> c(a, b) <- functionReturningTwoValues()
Error in c(a, b) <- functionReturningTwoValues() : object 'a' not found
haruskah saya benar-benar melakukan hal berikut?
R> r <- functionReturningTwoValues()
R> a <- r[1]; b <- r[2]
atau akankah programmer R menulis sesuatu seperti ini:
R> functionReturningTwoValues <- function() {return(list(first=1, second=2))}
R> r <- functionReturningTwoValues()
R> r$first
[1] 1
R> r$second
[1] 2
--- diedit untuk menjawab pertanyaan Shane ---
Saya tidak benar-benar perlu memberi nama ke bagian nilai hasil. Saya menerapkan satu fungsi agregat ke komponen pertama dan yang lain ke komponen kedua ( min
dan max
. Jika itu adalah fungsi yang sama untuk kedua komponen saya tidak perlu membelah mereka).
r
return-value
variable-assignment
assign
multiple-results
mariotomo
sumber
sumber
attr
nilai pengembalian Anda.Jawaban:
(1) daftar [...] <- Saya telah memposting ini lebih dari satu dekade yang lalu di r-help . Sejak itu telah ditambahkan ke paket gsubfn. Itu tidak memerlukan operator khusus tetapi mengharuskan sisi kiri ditulis menggunakan
list[...]
seperti ini:Jika Anda hanya membutuhkan komponen pertama atau kedua ini semua berfungsi juga:
(Tentu saja, jika Anda hanya membutuhkan satu nilai saja
functionReturningTwoValues()[[1]]
ataufunctionReturningTwoValues()[[2]]
akan cukup.)Lihat utas r-bantuan yang dikutip untuk contoh lebih lanjut.
(2) dengan Jika maksudnya hanya untuk menggabungkan beberapa nilai kemudian dan nilai kembali dinamai maka alternatif sederhana adalah dengan menggunakan
with
:(3) melampirkan Alternatif lain adalah melampirkan:
TAMBAH:
with
danattach
sumber
list
dan[<-.result
seperti yang ditunjukkan di sana?Saya entah bagaimana tersandung pada peretasan pintar ini di internet ... Saya tidak yakin apakah ini jahat atau indah, tetapi ini memungkinkan Anda membuat operator "ajaib" yang memungkinkan Anda membongkar beberapa nilai balik ke dalam variabel mereka sendiri. The
:=
Fungsi didefinisikan di sini , dan termasuk di bawah ini untuk anak cucu:Dengan itu, Anda dapat melakukan apa yang Anda cari:
Saya tidak tahu bagaimana perasaan saya tentang itu. Mungkin Anda mungkin merasa terbantu di ruang kerja interaktif Anda. Menggunakannya untuk membangun (dapat kembali) perpustakaan yang dapat digunakan (untuk konsumsi massal) mungkin bukan ide terbaik, tapi saya rasa itu terserah Anda.
... Anda tahu apa yang mereka katakan tentang tanggung jawab dan kekuasaan ...
sumber
:=
operator mucho dengan cara yang jauh lebih mudah :-)Biasanya saya membungkus output ke dalam daftar, yang sangat fleksibel (Anda dapat memiliki kombinasi angka, string, vektor, matriks, array, daftar, objek dalam output)
jadi seperti:
sumber
Saya pikir ini berhasil.
sumber
Saya mengumpulkan paket R zeallot untuk mengatasi masalah ini. zeallot termasuk operator penugasan ganda atau pembongkar tugas
%<-%
,. LHS operator adalah sejumlah variabel untuk ditetapkan, dibuat menggunakan panggilanc()
. RHS operator adalah vektor, daftar, bingkai data, objek tanggal, atau objek kustom apa pun dengandestructure
metode yang diterapkan (lihat?zeallot::destructure
).Berikut adalah beberapa contoh berdasarkan pada pos asli,
Lihatlah sketsa paket untuk informasi dan contoh lebih lanjut.
sumber
Tidak ada jawaban yang tepat untuk pertanyaan ini. Saya sangat bergantung pada apa yang Anda lakukan dengan data. Dalam contoh sederhana di atas, saya akan sangat menyarankan:
Apakah penting bahwa nilai 1 dan 2 di atas memiliki nama? Dengan kata lain, mengapa penting dalam contoh ini bahwa 1 dan 2 diberi nama a dan b, bukan hanya r [1] dan r [2]? Satu hal penting untuk dipahami dalam konteks ini adalah bahwa a dan b juga merupakan vektor dengan panjang 1. Jadi, Anda tidak benar-benar mengubah apa pun dalam proses membuat penugasan itu, selain memiliki 2 vektor baru yang tidak memerlukan subskrip untuk dirujuk:
Anda juga dapat menetapkan nama ke vektor asli jika Anda lebih suka merujuk surat daripada indeks:
[Sunting] Mengingat bahwa Anda akan menerapkan min dan maks ke setiap vektor secara terpisah, saya akan menyarankan menggunakan matriks (jika a dan b akan memiliki panjang dan tipe data yang sama) atau bingkai data (jika a dan b akan menjadi panjang yang sama tetapi dapat berupa tipe data yang berbeda) atau gunakan daftar seperti pada contoh terakhir Anda (jika panjangnya bisa berbeda dan tipe data).
sumber
r[1]
dapat membantu memperjelas hal-hal (baik-baik saja, tidak jika nama sukaa
menggantikannya).Daftar tampaknya sempurna untuk tujuan ini. Misalnya dalam fungsi yang Anda miliki
program utama
sumber
Ya untuk pertanyaan kedua dan ketiga Anda - itulah yang perlu Anda lakukan karena Anda tidak dapat memiliki beberapa 'nilai' di sebelah kiri tugas.
sumber
Bagaimana kalau menggunakan assign?
Anda dapat mengirimkan nama-nama variabel yang ingin Anda sampaikan dengan referensi.
Jika Anda perlu mengakses nilai yang ada, kebalikannya
assign
adalahget
.sumber
r <- function() { return(list(first=1, second=2)) }
dan merujuk hasil menggunakanr$first
danr$second
.Jika Anda ingin mengembalikan output fungsi Anda ke Lingkungan Global, Anda dapat menggunakan
list2env
, seperti dalam contoh ini:Fungsi ini akan membuat tiga objek di Lingkungan Global Anda:
sumber
[A] Jika masing-masing foo dan bar adalah angka tunggal, maka tidak ada yang salah dengan c (foo, bar); dan Anda juga dapat memberi nama komponen: c (Foo = foo, Bar = bar). Jadi Anda dapat mengakses komponen hasil 'res' sebagai res [1], res [2]; atau, dalam kasus bernama, sebagai res ["Foo"], res ["BAR"].
[B] Jika foo dan bar adalah vektor dari jenis dan panjang yang sama, maka sekali lagi tidak ada yang salah dengan mengembalikan cbind (foo, bar) atau rbind (foo, bar); juga bisa disebut. Dalam kasus 'cbind', Anda akan mengakses foo dan bar sebagai res [, 1], res [, 2] atau sebagai res [, "Foo"], res [, "Bar"]. Anda mungkin juga lebih suka mengembalikan kerangka data daripada matriks:
dan akses mereka sebagai res $ Foo, res $ Bar. Ini juga akan bekerja dengan baik jika foo dan bilah memiliki panjang yang sama tetapi tidak dari jenis yang sama (misalnya foo adalah vektor angka, bilah vektor string karakter).
[C] Jika foo dan bar cukup berbeda untuk tidak digabungkan dengan nyaman seperti di atas, maka Anda harus pasti mengembalikan daftar.
Misalnya, fungsi Anda mungkin cocok dengan model linier dan juga menghitung nilai prediksi, sehingga Anda bisa melakukannya
dan kemudian Anda akan melakukannya
return list(Foo=foo,Bar=bar)
dan kemudian mengakses ringkasan sebagai res $ Foo, nilai yang diprediksi sebagai res $ Barsumber: http://r.789695.n4.nabble.com/How-to-return-multiple-values-in-a-function-td858528.html
sumber
Untuk mendapatkan beberapa output dari suatu fungsi dan menyimpannya dalam format yang diinginkan, Anda dapat menyimpan output ke hard disk Anda (di direktori kerja) dari dalam fungsi dan kemudian memuatnya dari luar fungsi:
sumber
Dengan R 3.6.1, saya dapat melakukan hal berikut
sumber