จะตรวจสอบว่า object (ตัวแปร) ถูกกำหนดใน R ได้อย่างไร?


294

ฉันต้องการตรวจสอบว่ามีการกำหนดตัวแปรบางตัวใน R - โดยไม่ได้รับข้อผิดพลาดหรือไม่ ฉันจะทำสิ่งนี้ได้อย่างไร

ความพยายามของฉัน (ไม่สำเร็จ):

> is.na(ooxx)
Error: object 'ooxx' not found
> is.finite(ooxx)
Error: object 'ooxx' not found

ขอบคุณ!

คำตอบ:


448

คุณต้องการexists():

R> exists("somethingUnknown")
[1] FALSE
R> somethingUnknown <- 42
R> exists("somethingUnknown")
[1] TRUE
R> 

3
@Gavin & Dirk คุณเป็นคนที่ดีต่อกัน :) ทางออกเดียวคือคุณโยนเหรียญ (เบอร์นูลีกับ p = 0.5 :-)) ใครจะได้รับการยอมรับ! :-)
TMS

29
@tim ถ้าคุณอยู่ในฟังก์ชั่นหายไป () คือสิ่งที่คุณต้องการ
CousinCocaine

2
อาจมีเล่ห์เหลี่ยมเล็กน้อยหากตรวจสอบองค์ประกอบรายการ: stackoverflow.com/q/7719741
TMS

5
แล้ว op ต้องการอะไร - ใช้ชื่อตัวแปรไม่ใช่ในเครื่องหมายคำพูด?
ทิม

109

ดู?existsคำจำกัดความของ "... ถูกกำหนด" เช่น

> exists("foo")
[1] FALSE
> foo <- 1:10
> exists("foo")
[1] TRUE

7
คุณชนะภายใน 52 วินาที :)
Dirk Eddelbuettel

9
@DirkEddelbuettel ดีถ้าคุณจะใช้ชื่อวัตถุยาวขัน ;-)
กาวินซิมป์สัน

2
หึ เกิดขึ้นกับฉันตลอดเวลาเมื่อฉันกำลังทดสอบตัวอย่างก่อนโพสต์ Gavin หรือ Josh ได้ตอบคำถามไปแล้ว
Maiasaura

60

หากคุณอยู่ในฟังก์ชั่นหายไป () คือสิ่งที่คุณต้องการ

exchequer = function(x) {
    if(missing(x)){
        message("x is missing… :-(")
    }
}

exchequer()
x is missing… :-(

missingอย่างไรก็ตามใช้ได้กับอาร์กิวเมนต์ของฟังก์ชันเท่านั้น คุณไม่สามารถทำหรือคุณจะได้รับfoo <- function(x) {missing(x); missing(y)} foo(1) > Error in missing(y) : 'missing' can only be used for arguments
Dannid

45

existsเป็นคนอื่นได้ชี้ให้เห็นคุณกำลังมองหา โปรดทราบว่าการใช้existsกับชื่อที่ใช้โดยแพ็กเกจพื้นฐานของ R จะคืนค่าจริงโดยไม่คำนึงว่าคุณกำหนดตัวแปรไว้หรือไม่:

> exists("data")
[1] TRUE

ในการหลีกเลี่ยงปัญหานี้ (ตามที่ Bazz ชี้ให้เห็น?exists) ให้ใช้inheritsอาร์กิวเมนต์:

> exists("data", inherits = FALSE)
[1] FALSE

foo <- TRUE
> exists("foo", inherits = FALSE)
[1] TRUE

แน่นอนถ้าคุณต้องการค้นหาชื่อพื้นที่ของแพ็คเกจที่แนบมาสิ่งนี้จะสั้น:

> exists("data.table")
[1] FALSE
require(data.table)
> exists("data.table", inherits = FALSE)
[1] FALSE
> exists("data.table")
[1] TRUE

สิ่งเดียวที่ฉันสามารถนึกได้คือการค้นหาในแพ็คเกจที่แนบมา แต่ไม่ได้อยู่ในแพ็คเกจพื้นฐานคือ:

any(sapply(1:(which(search() == "tools:rstudio") - 1L),
           function(pp) exists(_object_name_, where = pp, inherits = FALSE)))

เปรียบเทียบการแทนที่_object_name_ด้วย"data.table"( TRUE) กับ"var"( FALSE)

(แน่นอนถ้าคุณไม่ได้อยู่ใน RStudio ฉันคิดว่าสภาพแวดล้อมที่แนบมาโดยอัตโนมัติเป็นครั้งแรก"package:stats")


2
การเล่นโดยใช้การโต้แย้งinherits = FALSEดูเหมือนว่าจะแยกสิ่งต่าง ๆ ในสภาพแวดล้อมของโลก เสียงนั้นใช่ไหม
CJB

1
@Bazz คุณถูกต้อง; ฉันแก้ไขสิ่งนี้เป็นคำตอบ
MichaelChirico

2
ความคิดเห็นนี้ควรจะสูงขึ้นเนื่องจากฉันใช้ชื่อตัวแปร "ข้อมูล" เพียงใช้อยู่ทำให้ฉันมีปัญหาบางอย่างในตอนแรก
mzm

25

หากคุณไม่ต้องการใช้คำพูดคุณสามารถใช้deparse(substitute())เคล็ดลับที่ฉันพบในส่วนตัวอย่างของ?substitute:

is.defined <- function(sym) {
  sym <- deparse(substitute(sym))
  env <- parent.frame()
  exists(sym, env)
}

is.defined(a)
# FALSE
a <- 10
is.defined(a)
# TRUE

1
คุณสามารถforceหรือประเมินมันในฟังก์ชั่นเช่นนี้:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
chinsoon12

1

อาจมีสถานการณ์ที่คุณไม่ทราบชื่อของตัวแปรที่คุณกำลังมองหาอย่างแน่นอนเช่นเมื่ออาร์เรย์ของผลลัพธ์ถูกสร้างโดยระบบการจัดคิว สิ่งเหล่านี้สามารถแก้ไขได้ด้วย "ls" และอาร์กิวเมนต์ "รูปแบบ" ซึ่งคาดว่าจะแสดงออกเป็นปกติ

ฟังก์ชั่น "ที่มีอยู่" สามารถนำไปใช้งานใหม่ได้เช่นกัน

exists <-function(variablename) {
   #print(ls(env=globalenv()))
   return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
}

ขณะเตรียมคำตอบนี้ฉันรู้สึกประหลาดใจเล็กน้อยเกี่ยวกับความต้องการความต้องการสเปคของสภาพแวดล้อมเมื่อเรียกใช้ls ()จากภายในฟังก์ชัน ดังนั้นขอบคุณสำหรับสิ่งที่ stackoverflow! นอกจากนี้ยังมีแอตทริบิวต์ "all.names" ที่ฉันควรตั้งให้เป็นจริง แต่ถูกละไว้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.