2015-12-03 28 views
16

Gần đây, tôi đã phải đối mặt với một hành vi trong table chức năng đó không phải là những gì tôi đã mong đợi:Bất ngờ hành vi của bảng chức năng với "NaN" giá trị

Ví dụ, chúng ta hãy lấy vectơ sau:

ex_vec <- c("Non", "Non", "Nan", "Oui", "NaN", NA) 

Nếu tôi kiểm tra NA giá trị trong vector của tôi, "NaN" không được xem là một (như dự kiến):

is.na(ex_vec) 
# [1] FALSE FALSE FALSE FALSE FALSE TRUE 

Nhưng nếu tôi cố gắng để nhận các giá trị tần số khác nhau:

table(ex_vec) 
#ex_vec 
#Nan Non Oui 
# 1 2 1 

"NaN" không xuất hiện trong bảng.

Tuy nhiên, nếu tôi "yêu cầu" table để hiển thị các NA giá trị, tôi có được điều này:

table(ex_vec, useNA="ifany") 
#ex_vec 
# Nan NaN Non Oui <NA> 
# 1 1 2 1 1 

Vì vậy, chuỗi kí tự "NaN" được coi là một NA giá trị bên trong table cuộc gọi, trong khi được điều trị tại các ouput dưới dạng giá trị không phải là NA.

Tôi biết (sẽ tốt hơn và) tôi có thể giải quyết vấn đề của mình bằng cách chuyển đổi véc tơ của tôi thành factor nhưng dù sao, tôi thực sự muốn biết điều gì đang xảy ra ở đây. Có ai có ý tưởng gì không?

+1

điều này chỉ là sử dụng cơ bản .. như "tại sao 'sum (c (1, NA)) 'return NA?" 'table (..., exclude = if (useNA ==" no ") c (NA, NaN), useNA = c (" không "," ifany "," luôn luôn ")' Tôi không hiểu mục đích của những câu trả lời này – rawr

+4

@rawr để giải thích lý do tại sao a * string * được coi là giá trị 'NaN'? Đây không phải là cách sử dụng được hỏi, nhưng tại sao nó lại ít rõ ràng hơn so với ví dụ tổng của bạn. Ý tôi là: 'NaN! =" NaN "' vậy tại sao 'NaN '' bị loại trừ vì nó không phải là một phần của vector loại trừ) – Tensibai

+0

@Tensibai một lần nữa, các tài liệu nói 'loại trừ: các mức để loại bỏ cho tất cả các yếu tố' _levels_ không 'NA' cũng không phải là' NaN', chúng là _strings_ .. aways _strings_ try 'table (1, exclude = 1)' – rawr

Trả lời

13

Khi factor phù hợp lên mức cho một vector nó chuyển đổi danh sách exclude của nó với các loại tương tự như các vector đầu vào:

exclude <- as.vector(exclude, typeof(x)) 

vì vậy nếu danh sách loại trừ của bạn có NaN và vector của bạn là nhân vật, điều này xảy ra:

as.vector(exclude, typeof(letters)) 
[1] NA "NaN" 

Oh dear. Bây giờ, các chuỗi "NaN" thực sẽ bị loại trừ.

Để khắc phục, hãy sử dụng exclude=NA trong table (và factor nếu bạn đang tạo các yếu tố có thể ảnh hưởng đến điều này).

tôi làm tình yêu này trong các tài liệu cho factor:

There are some anomalies associated with factors that have ‘NA’ as 
a level. It is suggested to use them sparingly, e.g., only for 
tabulation purposes. 

yên tâm ...

+0

Cảm ơn bạn rất nhiều vì câu trả lời rất rõ ràng này (Tôi cũng thích trích dẫn từ yếu tố tài liệu!) – Cath

5

ý tưởng đầu tiên đến với tâm trí của tôi là để có một cái nhìn tại table định nghĩa mà bắt đầu bằng cách:

> table 
function (..., exclude = if (useNA == "no") c(NA, NaN), useNA = c("no", 
    "ifany", "always"), dnn = list.names(...), deparse.level = 1) 
{ 

Âm thanh hợp lý, bởi bảng mặc định loại trừ NANaN.

Đào trong mã bảng, chúng tôi thấy rằng nếu x không phải là một yếu tố nó ép buộc nó vào một yếu tố (không có gì mới ở đây, nó được nói trong tài liệu).

else { 
     a <- factor(a, exclude = exclude) 

tôi không tìm thấy bất cứ điều gì khác mà có thể đã ảnh hưởng đến đầu vào để ép buộc "NaN" vào NA giá trị.

Vì vậy, nhìn vào yếu tố để có được những lý do tại sao chúng tôi tìm ra nguyên nhân gốc rễ:

> factor 
function (x = character(), levels, labels = levels, exclude = NA, 
    ordered = is.ordered(x), nmax = NA) 
{ 
[...] # Snipped for brievety 
    exclude <- as.vector(exclude, typeof(x)) 
    x <- as.character(x) 
    levels <- levels[is.na(match(levels, exclude))] # defined in the snipped part above, is the sorted unique values of input vector, coerced to char. 
    f <- match(x, levels) 
[...] 
    f 
} 

Ở đây chúng ta đã nhận nó, tham số loại trừ, thậm chí là NA giá trị được ép buộc vào một vector nhân vật.

Vì vậy, những gì xảy ra là:

> ex_vec <- c("Non", "Non", "Nan", "Oui", "NaN", NA) 
> excludes<-c(NA,NaN) 
> as.vector(excludes,"character") 
[1] NA "NaN" 
> match(ex_vec,as.vector(excludes,"character")) 
[1] NA NA NA NA 2 1 

Chúng tôi làm trận đấu vật "NaN" như loại trừ vector như bị ép buộc để nhân vật trước khi so sánh.

+0

Cảm ơn @Tensibai vì lời giải thích! Tại sao "NaN" vẫn được sắp xếp trong các kết quả 'bảng' như một giá trị thông thường và không phải ở cuối với' '? – Cath

+1

@CathG Bởi vì các cấp được sắp xếp lúc tạo;) Xem chú thích trong mã yếu tố trên dòng 'mức', một khi không bị loại trừ, chúng trở thành mục nhập bình thường – Tensibai

+1

@CathG khi tham số bảng được đặt thành thứ khác 'không' chúng không bị xóa và được coi là những chuỗi bình thường không có ý nghĩa đặc biệt – Tensibai

Các vấn đề liên quan