简体   繁体   English

给定任何类型的向量,如何获得相同 class 的 NA 值?

[英]Given a vector of any type, how can I get an NA value of the same class?

Suppose I want to do something like:假设我想做类似的事情:

mask_values <- function(x, mask) ifelse(mask, x, NA)

The purpose of this function is to take a vector and replace some of its values with NA based on the value of mask .这个 function 的目的是取一个向量并根据mask的值用 NA 替换它的一些值。 However, this function doesn't guarantee that the return type is always the same as the input x .但是,此 function 不保证返回类型始终与输入x相同。 For example:例如:

date_vec <- rep(lubridate::today(), 10)
my_mask <- rep(c(TRUE, FALSE), length.out = 10)
class(mask_values(date_vec, my_mask))

which yields "numeric" rather than the desired "Date" .这会产生"numeric"而不是所需的"Date" So I try switching to dplyr::if_else , which is supposed to preserve types:所以我尝试切换到dplyr::if_else ,它应该保留类型:

mask_values <- function(x, mask) dplyr::if_else(mask, x, NA)
class(mask_values(date_vec, my_mask))

However, if_else also requires the input types to be the same as each other, and NA has type "logical", which means I get this error:但是, if_else还要求输入类型彼此相同,并且NA具有“逻辑”类型,这意味着我收到此错误:

Error: `false` must be a `Date` object, not a logical vector.

So it seems that if I want to use if_else in order to preserve the input type, I need to be able to obtain an NA value with the same class as the input.因此,如果我想使用if_else来保留输入类型,我需要能够获得与输入相同的 class 的 NA 值。 Is there a reliable way to do this for any class?对于任何 class 是否有可靠的方法来执行此操作? One possibility seems to be x[NA] , but I'm not sure if that is a universal solution or if it just happens to work with the examples that I've tested.一种可能性似乎是x[NA] ,但我不确定这是否是一个通用解决方案,或者它是否恰好适用于我测试过的示例。 You can assume that the only classes that matter are "vector-like" classes for which NA values exist, such as Date and POSIXct, as well as all the basic R data types (logical, character, numeric, etc.).您可以假设唯一重要的类是存在 NA 值的“类向量”类,例如 Date 和 POSIXct,以及所有基本的 R 数据类型(逻辑、字符、数字等)。

Alternatively, is there another way to implement my mask_values function such that the return value always has the same type as x ?或者,是否有另一种方法来实现我的mask_values function 使得返回值始终具有与x相同的类型?

I recommend avoiding ifelse whenever possible.我建议尽可能避免ifelse It is quite inefficient and as you have seen also quirky regarding what it returns (although that is well documented).它的效率很低,而且正如您所见,它返回的内容也很古怪(尽管有据可查)。 I rarely use it and, if I do use it, only for interactive use and not programmatically.我很少使用它,如果我确实使用它,仅用于交互使用,而不是以编程方式使用。

The canonical and safe way of setting values to NA in base R is is.na<- .在基础 R 中将值设置为NA的规范且安全的方法是is.na<- (Note that it supports logical and positional indexing. mask could also be a numeric vector.) (请注意,它支持逻辑和位置索引。 mask也可以是数字向量。)

mask_values <- function(x, mask) {
  is.na(x) <- mask
  x
}

#or simply this:
#mask_values <- `is.na<-` 
#i.e., `is.na<-` is already what you want.

class(mask_values(date_vec, my_mask))
#[1] "Date"

Alternatively, you can also use simple subset-assignment.或者,您也可以使用简单的子集分配。 NA is a logical value. NA是一个逻辑值。 (If you create it like this. It can be coerced to other types and of course you can specify it as other types with NA_real_ etc.) If you assign a logical vector into any other vector, it will be coerced to that other vector's type (because "logical" is the most primitive type). (如果您像这样创建它。它可以被强制转换为其他类型,当然您可以使用NA_real_等将其指定为其他类型。)如果将逻辑向量分配给任何其他向量,它将被强制转换为其他向量的类型(因为“逻辑”是最原始的类型)。

mask_values <- function(x, mask) {
  x[mask] <- NA
  x
}

class(mask_values(date_vec, my_mask))
#[1] "Date"

Btw., this subset-assignment is how the is.na<-.default method is defined.顺便说一句,这个子集分配是is.na<-.default方法的定义方式。

I prefer doing subset-assignment explicitly in my code but occasionally the convenience function replace can be useful.我更喜欢在我的代码中明确地进行子集分配,但偶尔方便 function replace可能很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM