183

我有一个带有一些数字列的数据框。某些行的值为 0,在统计分析中应视为空值。在R中将所有0值替换为NULL的最快方法是什么?

4

9 回答 9

306

将所有零替换为 NA:

df[df == 0] <- NA



解释

1.这不是NULL您应该想要替换零的东西。正如它所说?'NULL'

NULL 表示 R 中的空对象

这是独一无二的,我想,可以被视为最无信息和空洞的对象。1那么就不足为奇了

data.frame(x = c(1, NULL, 2))
#   x
# 1 1
# 2 2

也就是说,R 不为这个空对象保留任何空间。2同时,看着?'NA'我们看到

NA 是长度为 1 的逻辑常数,其中包含缺失值指示符。NA 可以强制转换为除 raw 之外的任何其他向量类型。

重要的NA是,长度为 1,以便 R 为其保留一些空间。例如,

data.frame(x = c(1, NA, 2))
#    x
# 1  1
# 2 NA
# 3  2

此外,数据框结构要求所有列具有相同数量的元素,这样就不会出现“漏洞”(即NULL值)。

现在,您可以在数据框中用零替换零,NULL即完全删除包含至少一个零的所有行。var例如,当使用 、covcor时,这实际上等同于首先将零替换为NA并将其值设置use"complete.obs"。然而,这通常不能令人满意,因为它会导致额外的信息丢失。

2.df == 0在解决方案中,我使用矢量化,而不是运行某种循环。df == 0返回(尝试)一个与 相同大小的矩阵,其中包含和df的条目。此外,我们还可以将此矩阵传递给子集(参见参考资料)。最后,虽然结果非常直观,但给出预期效果可能看起来很奇怪。赋值运算符确实并不总是那么聪明,并且不能以这种方式与其他一些对象一起工作,但它可以与数据帧一起工作;见。TRUEFALSE[...]?'['df[df == 0]df[df == 0] <- NA<-?'<-'


1集合论中的空集感觉有某种关联。
2与集合论的另一个相似之处:空集是每个集合的子集,但我们不为它保留任何空间。

于 2012-06-14T16:09:45.513 回答
48

让我假设您的 data.frame 是不同数据类型的混合,并非所有列都需要修改。

仅修改第 12 到 18 列(总共 21 列),只需执行此操作

df[, 12:18][df[, 12:18] == 0] <- NA
于 2015-02-20T14:08:32.130 回答
37

dplyr::na_if()是一个选项:

library(dplyr)  

df <- data_frame(col1 = c(1, 2, 3, 0),
                 col2 = c(0, 2, 3, 4),
                 col3 = c(1, 0, 3, 0),
                 col4 = c('a', 'b', 'c', 'd'))

na_if(df, 0)
# A tibble: 4 x 4
   col1  col2  col3 col4 
  <dbl> <dbl> <dbl> <chr>
1     1    NA     1 a    
2     2     2    NA b    
3     3     3     3 c    
4    NA     4    NA d
于 2018-07-04T16:52:53.947 回答
23

[<-没有该功能的另一种方法:

一个示例数据框dat(无耻地从@Chase 的答案中复制):

dat

  x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0

零可以用NA以下is.na<-函数替换:

is.na(dat) <- !dat


dat

   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA
于 2013-01-06T11:56:46.587 回答
14
#Sample data
set.seed(1)
dat <- data.frame(x = sample(0:2, 5, TRUE), y = sample(0:2, 5, TRUE))
#-----
  x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0

#replace zeros with NA
dat[dat==0] <- NA
#-----
   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA
于 2012-06-14T16:11:26.367 回答
13

因为有人要求这个的 Data.Table 版本,并且因为给定的 data.frame 解决方案不适用于 data.table,所以我在下面提供了解决方案。

基本上,使用:=运算符 -->DT[x == 0, x := NA]

library("data.table")

status = as.data.table(occupationalStatus)

head(status, 10)
    origin destination  N
 1:      1           1 50
 2:      2           1 16
 3:      3           1 12
 4:      4           1 11
 5:      5           1  2
 6:      6           1 12
 7:      7           1  0
 8:      8           1  0
 9:      1           2 19
10:      2           2 40


status[N == 0, N := NA]

head(status, 10)
    origin destination  N
 1:      1           1 50
 2:      2           1 16
 3:      3           1 12
 4:      4           1 11
 5:      5           1  2
 6:      6           1 12
 7:      7           1 NA
 8:      8           1 NA
 9:      1           2 19
10:      2           2 40
于 2016-06-02T00:58:09.240 回答
7

如果有人通过谷歌到达这里寻找相反的东西(即如何用 0 替换 data.frame 中的所有 NA),答案是

df[is.na(df)] <- 0

或者

使用 dplyr / tidyverse

library(dplyr)
mtcars %>% replace(is.na(.), 0)
于 2020-04-18T05:09:35.937 回答
4

您只能在数字字段中替换0NA(即排除因子之类的内容),但它可以逐列地工作:

col[col == 0 & is.numeric(col)] <- NA

使用函数,您可以将其应用于整个数据框:

changetoNA <- function(colnum,df) {
    col <- df[,colnum]
    if (is.numeric(col)) {  #edit: verifying column is numeric
        col[col == -1 & is.numeric(col)] <- NA
    }
    return(col)
}
df <- data.frame(sapply(1:5, changetoNA, df))

尽管您可以将 替换为1:5数据框中的列数,或者替换为1:ncol(df).

于 2015-01-24T19:46:44.270 回答
1

如果您像我一样,在想知道如何用 NA 替换数据框中的所有值时来到这里,那就是:

df[,] <- NA

于 2021-05-21T12:57:09.070 回答