是否可以跳过"+"运算符中的NA值?

M. *_*eil 13 r sum vector lapply cbind

我想在R中计算一个等式.我不想使用该函数,sum因为它返回1个值.我想要完整的值向量.

x = 1:10
y = c(21:29,NA)
x+y
 [1] 22 24 26 28 30 32 34 36 38 NA

x = 1:10
y = c(21:30)
x+y
 [1] 22 24 26 28 30 32 34 36 38 40
Run Code Online (Sandbox Code Playgroud)

我不想要:

sum(x,y, na.rm = TRUE)
[1] 280
Run Code Online (Sandbox Code Playgroud)

哪个不返回矢量.

这是一个玩具示例,但我有一个更复杂的等式,使用长度为84647个元素的多个向量.

这是我的另一个例子:

x = 1:10
y = c(21:29,NA)
z = 11:20
a = c(NA,NA,NA,30:36)
5 +2*(x+y-50)/(x+y+z+a) 
 [1]       NA       NA       NA 4.388889 4.473684 4.550000 4.619048 4.681818 4.739130       NA
Run Code Online (Sandbox Code Playgroud)

G. *_*eck 16

1)%+%定义自定义+运算符:

`%+%` <- function(x, y)  mapply(sum, x, y, MoreArgs = list(na.rm = TRUE))
5 + 2 * (x %+% y - 50) / (x %+% y %+% z %+% a)
Run Code Online (Sandbox Code Playgroud)

赠送:

[1] 3.303030 3.555556 3.769231 4.388889 4.473684 4.550000 4.619048 4.681818
[9] 4.739130 3.787879
Run Code Online (Sandbox Code Playgroud)

以下是一些简单的例子:

1 %+% 2
## [1] 3

NA %+% 2
## [1] 2

2 %+% NA
## [1] 2

NA %+% NA
## [1] 0
Run Code Online (Sandbox Code Playgroud)

2)na2zero另一种可能性是定义一个将NA映射到0的函数,如下所示:

na2zero <- function(x) ifelse(is.na(x), 0, x)

X <- na2zero(x)
Y <- na2zero(y)
Z <- na2zero(z)
A <- na2zero(a)

5 + 2 * (X + Y - 50) / (X + Y + Z + A)
Run Code Online (Sandbox Code Playgroud)

赠送:

[1] 3.303030 3.555556 3.769231 4.388889 4.473684 4.550000 4.619048 4.681818
[9] 4.739130 3.787879
Run Code Online (Sandbox Code Playgroud)

3)结合以上结合(1)与(2)中的想法的变化是:

X <- x %+% 0
Y <- y %+% 0
Z <- z %+% 0
A <- a %+% 0

5 + 2 * (X + Y - 50) / (X + Y + Z + A)
Run Code Online (Sandbox Code Playgroud)

4)numeric0类我们可以"numeric0"用自己的+运算符定义一个自定义类:

as.numeric0 <- function(x) structure(x, class = "numeric0")
`+.numeric0` <- `%+%`

X <- as.numeric0(x)
Y <- as.numeric0(y)
Z <- as.numeric0(z)
A <- as.numeric0(a)

5 + 2 * (X + Y - 50) / (X + Y + Z + A)
Run Code Online (Sandbox Code Playgroud)

注意:使用的输入是问题中的输入,即:

x = 1:10
y = c(21:29,NA)
z = 11:20
a = c(NA,NA,NA,30:36)
Run Code Online (Sandbox Code Playgroud)


M--*_*M-- 14

使用rowSums:

要详细说明我的注释,您可以连接向量,然后在结果矩阵上应用计算.这是您在问题结尾处提供的示例的解决方案;

5 + 2 * (rowSums(cbind(x,y), na.rm = T)-50)/(rowSums(cbind(x,y,z,a), na.rm = T))

#  [1] 3.303030 3.555556 3.769231 4.388889 4.473684 4.550000 4.619048 4.681818 
#  [9] 4.739130 3.787879
Run Code Online (Sandbox Code Playgroud)

重新制作NA:

我在这里看到的解决方案是NA在向量中替换; 我认为这也会有所帮助:

y[is.na(y)] <- 0 #indexing NA values and replacing with zero
Run Code Online (Sandbox Code Playgroud)


Mou*_*d_S 6

您可以使用 ifelse()

x = 1:10
y = c(21:29,NA)
x+y

[1] 22 24 26 28 30 32 34 36 38 NA

x + ifelse(is.na(y), 0, y)

[1] 22 24 26 28 30 32 34 36 38 10
Run Code Online (Sandbox Code Playgroud)


d.b*_*d.b 6

数据

x = 1:10
y = c(21:29,NA)
x+y
# [1] 22 24 26 28 30 32 34 36 38 NA
Run Code Online (Sandbox Code Playgroud)

1

foo1 = function(...){
    return(rowSums(cbind(...), na.rm = TRUE))
}
foo1(x, y)
# [1] 22 24 26 28 30 32 34 36 38 10
Run Code Online (Sandbox Code Playgroud)

2

foo2 = function(...){
    Reduce('+', lapply(list(...), function(x) replace(x, is.na(x), 0)))
}
foo2(x, y)
# [1] 22 24 26 28 30 32 34 36 38 10
Run Code Online (Sandbox Code Playgroud)

  • 不需要转到`data.frame`,而是使用`cbind()`来保持它作为矩阵并避免额外的转换(`rowSums`只会转换回矩阵). (4认同)

Hon*_*Ooi 5

只是为了laffs:

x=1:10
y=c(21:29, NA)

"[<-"(x, is.na(x), 0) + "[<-"(y, is.na(y), 0)
# [1] 22 24 26 28 30 32 34 36 38 10
Run Code Online (Sandbox Code Playgroud)

这再次说明了R中的所有内容都是函数的事实(并且还表明R解释器足够聪明,可以在需要时将字符串转换为函数).

语法上有甜味:

na.zero <- function(x)
{
    "[<-"(x, is.na(x), 0)
}
na.zero(x) + na.zero(y)
# [1] 22 24 26 28 30 32 34 36 38 10
Run Code Online (Sandbox Code Playgroud)

更广泛适用的版本:

na.replace <- function(x, value)
{
    "[<-"(x, is.na(x), value)
}
na.replace(x, 1) * na.replace(x, 1)
# [1]   1   4   9  16  25  36  49  64  81 100
Run Code Online (Sandbox Code Playgroud)