Saya terkejut mengetahui bahwa R tidak datang dengan fungsi praktis untuk memeriksa apakah angkanya adalah integer.
is.integer(66) # FALSE
File bantuan memperingatkan :
is.integer(x)
tidak menguji apakahx
berisi bilangan bulat! Untuk itu, gunakanround
, seperti pada fungsiis.wholenumber(x)
pada contoh.
Contoh memiliki fungsi kustom sebagai "solusi"
is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol
is.wholenumber(1) # is TRUE
Jika saya harus menulis fungsi untuk memeriksa bilangan bulat, dengan asumsi saya belum membaca komentar di atas, saya akan menulis fungsi yang akan melakukan sesuatu di sepanjang baris
check.integer <- function(x) {
x == round(x)
}
Dimana pendekatan saya akan gagal? Apa pekerjaan Anda jika Anda berada dalam posisi hipotetis saya?
round(x)
diimplementasikan dengan benar, hasil penerapannya ke integer akan selalu menjadi integer itu ...is.integer
memeriksa konsep komputasi,check.integer
fungsi pengguna memeriksa sudut pandang matematika.Jawaban:
Alternatif lain adalah memeriksa bagian pecahan:
atau, jika Anda ingin memeriksa dalam toleransi tertentu:
sumber
x <- 5-1e-8; x%%1
memberikan 0.9999999 (yang akan berarti jikatol==1e-5
misalnya) yangx
merupakan bukan integer.min(abs(c(x%%1, x%%1-1))) < tol
alih - alihabs(min(x%%1, x%%1-1)) < tol
sebaliknya, Anda akan mendapatkanFALSE
bilangan bulat apa pun ...as.integer(x) == x
? Itu tidak akan menolak 3 atau 3.0 seperti yangis.integer(x)
akan terjadi, dan itu akan menangkap 3.1.Berikut solusi menggunakan fungsi yang lebih sederhana dan tanpa peretasan:
Terlebih lagi, Anda dapat menguji seluruh vektor sekaligus, jika Anda mau. Inilah fungsinya:
Anda dapat mengubahnya untuk digunakan
*apply
dalam kasus vektor, matriks, dll.sumber
if
else
bisa dilakukan dengan sederhanaisTRUE(test)
. Memang hanya itu yang Anda butuhkan untuk menggantiif
else
klausa danreturn
pernyataan karena R secara otomatis mengembalikan hasil evaluasi terakhir.testInteger(1.0000001)
[1] SALAHtestInteger(1.00000001)
[1] BENARall(a == as.integer(a))
mengatasi masalah ini! 'Membaca dokumentasi bahasa R,
as.integer
lebih berkaitan dengan bagaimana nomor disimpan daripada jika secara praktis setara dengan bilangan bulat.is.integer
tes jika nomor tersebut dideklarasikan sebagai integer. Anda dapat mendeklarasikan integer dengan meletakkan aL
setelahnya.Juga fungsi seperti
round
akan mengembalikan integer yang dideklarasikan, yang sedang Anda lakukanx==round(x)
. Masalah dengan pendekatan ini adalah apa yang Anda anggap praktis sebagai bilangan bulat. Contoh tersebut menggunakan presisi yang kurang untuk menguji kesetaraan.Jadi tergantung pada aplikasi Anda, Anda bisa mendapat masalah dengan cara itu.
sumber
Inilah satu cara yang tampaknya dapat diandalkan:
Solusi ini juga memungkinkan bilangan bulat dalam notasi ilmiah:
sumber
check.integer(1e4)
BENAR, sedangkancheck.integer(1e5)
SALAH.is.wholenumber
, atau solusi lain yang diberikan dalam jawaban lain. Ini seharusnya tidak berbeda:check.integer(1e22); check.integer(1e23)
. Anda jelas dapat mengubah regex untuk memperbaikinya, tetapi pendekatan ini mengerikan. (Komentar berasal dari atribusi dalam paket installr.)format(40, scientific = FALSE, digits = 20)
sebagai gantinya. Saya telah memperbarui jawabannya. Terima kasih sudah melihatnya.1.0000000000000001 == 1L [1] TRUE
. Tetapi solusi saya lebih baik jika Anda sudah mendapatkan nomor dalam bentuk stringcheck.integer("1000000000000000000000000000000000001") [1] TRUE
Tampaknya Anda tidak melihat kebutuhan untuk memasukkan beberapa toleransi kesalahan. Ini tidak akan diperlukan jika semua bilangan bulat dimasukkan sebagai bilangan bulat, namun kadang-kadang mereka datang sebagai hasil dari operasi aritmatika yang kehilangan beberapa presisi. Sebagai contoh:
Perhatikan bahwa ini bukan kelemahan R, semua perangkat lunak komputer memiliki beberapa batasan presisi.
sumber
Dari
Hmisc::spss.get
:pilihan yang jauh lebih aman, IMHO, karena "melewati" masalah presisi mesin. Jika Anda mencoba
is.integer(floor(1))
, Anda akan mendapatkanFALSE
. BTW, bilangan bulat Anda tidak akan disimpan sebagai bilangan bulat jika lebih besar dari.Machine$integer.max
nilai, yaitu, secara default 2147483647, jadi ubahinteger.max
nilainya, atau lakukan pemeriksaan alternatif ...sumber
x <- sqrt(2)^2
, kemudianall(floor(x) == x, na.rm = TRUE)
kembaliFALSE
Anda bisa menggunakan simple if condition seperti:
sumber
Di R, apakah suatu angka adalah numerik atau integer dapat ditentukan oleh fungsi kelas. Umumnya semua angka disimpan sebagai numerik dan untuk secara eksplisit mendefinisikan angka sebagai integer kita perlu menentukan 'L' setelah angka tersebut.
Contoh:
[1] "numerik"
[1] "integer"
Saya harap inilah yang dibutuhkan. Terima kasih :)
sumber
[UPDATE] =============================================== ===============
Sehubungan dengan jawaban [LAMA] di sini di bawah, saya telah menemukan bahwa itu berhasil karena saya telah meletakkan semua angka dalam satu vektor atom; salah satunya adalah karakter, jadi setiap orang menjadi karakter.
Jika kita menggunakan daftar (karena itu, pemaksaan tidak terjadi) semua tes lulus dengan benar kecuali satu
1/(1 - 0.98)
:, yang tetap anumeric
. Ini karenatol
parameternya secara default100 * .Machine$double.eps
dan angka itu jauh dari50
kurang dari dua kali lipatnya. Jadi, pada dasarnya, untuk jenis angka ini, kita harus memutuskan toleransi kita!Jadi jika Anda ingin semua tes menjadi
TRUE
, Anda bisaassertive::is_whole_number(x, tol = 200 * .Machine$double.eps)
Bagaimanapun, saya menegaskan bahwa IMO tegas tetap merupakan solusi terbaik.
Berikut di bawah ini reprex untuk [PEMBARUAN] ini.
Dibuat pada 2019-07-23 oleh paket reprex (v0.3.0)
[LAMA] =============================================== ==================
IMO solusi terbaik berasal dari
assertive
paket (yang, untuk saat ini, menyelesaikan semua contoh positif dan negatif di utas ini):Dibuat pada 2019-07-23 oleh paket reprex (v0.3.0)
sumber
Jika Anda memilih untuk tidak menulis fungsi Anda sendiri, coba
check.integer
dari package installr . Saat ini menggunakan jawaban VitoshKa.Coba juga
check.numeric(v, only.integer=TRUE)
dari package varhandle , yang memiliki keuntungan sebagai vektorisasi.sumber
Once juga bisa menggunakan
dplyr::near
:Ini berlaku untuk vektor apa pun
a
, dan memiliki parameter toleransi opsional.sumber
Saya tidak yakin apa yang ingin Anda capai. Tapi di sini ada beberapa pemikiran:
1. Convert to integer:
num = as.integer(123.2342)
2. Periksa apakah suatu variabel adalah integer:
is.integer(num)
typeof(num)=="integer"
sumber