繁体   English   中英

将所有 0 值替换为 NA

[英]Replace all 0 values to NA

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

将所有零替换为 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 ,即完全删除包含至少一个零的所有行。 例如,当使用varcovcor时,这实际上相当于首先用NA替换零并将use的值设置为"complete.obs" 然而,这通常不能令人满意,因为它会导致额外的信息丢失。

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


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

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

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

df[, 12:18][df[, 12:18] == 0] <- NA

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

没有[<-功能的替代方法:

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

dat

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

零可以通过is.na<-函数替换为NA

is.na(dat) <- !dat


dat

   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA
#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

因为有人要求这个的 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

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

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

或者

使用 dplyr / tidyverse

library(dplyr)
mtcars %>% replace(is.na(.), 0)

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

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:ncol(df)替换1:5

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

 df[,] <- NA

这是我为那些正在努力处理具有不同类型列的数据集的人所做的贡献,这些列具有代表缺失数据的多个值。

dat <- data_frame(numA = c(1, 0, 3, 4),
             numB = c(NA, 2, 3, 4),
             strC = c("0", "1.2", "NA", "2.4"),
             strD = c("Yes", "Yes", "missing", "No"))

假设在这个数据中,我们想用 NA 替换数字列中的 0 以及用NA替换字符/字符串值中的 ' NA ' 和 'missing' 值。 请注意, strC列中的 'NA' 是字符类型值,而不是所需的NA

dat
# A tibble: 4 x 4
  numA   numB  strC  strD   
  <dbl>  <dbl> <chr> <chr>  
1     1     NA 0     Yes    
2     0      2 1.2   Yes    
3     3      3 'NA'  missing
4     4      4 2.4   No 

首先,一个明显的例子,请注意,当将字符列转换为数值时,任何非数值字符串值都被强制转换为NA

as.numeric(dat$strC)
[1] 0.0 1.2  NA 2.4 

用索引回答:

dat[dat == "NA" | dat =="missing"] <- NA

但是,不要将其用于 0 ,因为它会将数字和字符 0 都更改为NA 这是因为"0" == 0在 R 中返回TRUE

dplyr::na_if 方法:

library(dplyr)

dat %>%
  lapply(na_if, y = "missing") %>%
  lapply(na_if, y = "NA") %>%
  lapply(na_if, y = 0) %>%  # DONT DO THIS! It converts string 0s to NA as well!
  data.frame()

在这里,我们将na_if函数应用于数据的每一列。 由于na_if不接受要转换为NA的多个值,因此我们需要为要转换为NA的每个值编写多行代码。 但是,将此函数与0一起简单使用会将数字和字符0 s 转换为NA 我们需要做点别的事情!

通过 na_if 函数使用 mutate cross 方法:

这是我最喜欢的解决方案。 在这里,我们检查列类型并根据需要应用na_if函数。 字符0保持不变,而所有需要的值都转换为NA

dat %>%
  mutate(across(where(is.numeric), ~na_if(., 0))) %>%
  mutate(across(where(is.character), ~na_if(., "NA"))) %>%
  mutate(across(where(is.character), ~na_if(., "missing")))

# A tibble: 4 x 4
   numA  numB strC  strD 
  <dbl> <dbl> <chr> <chr>
1     1    NA 0     Yes  
2    NA     2 1.2   Yes  
3     3     3 NA    NA   
4     4     4 2.4   No 

最后,可以使用nariar

nariar是一个最近的包,它引入了各种replace_with_函数。

library(naniar)

将所有 'NA' 和 'missing' 值替换为NA

dat %>%
  replace_with_na_all(~.x %in% c("NA", "missing"))

但是如果您将其与0一起使用,它仍然会错误地将字符 0 转换为NA

dat %>%
  replace_with_na_all(~.x %in% c(0, "NA", "missing"))

# A tibble: 4 x 4
   numA  numB strC  strD 
  <dbl> <dbl> <chr> <chr>
1     1    NA NA    Yes  
2    NA     2 1.2   Yes  
3     3     3 NA    NA   
4     4     4 2.4   No
#strC's first element should not be NA here!

因此,我们必须使用 replace_with_na_if 指定列类型:

dat %>%
  replace_with_na_if(is.character, ~.x %in% c("NA", "missing")) %>%
  replace_with_na_if(is.numeric, ~.x %in% c(0))

# A tibble: 4 x 4
   numA  numB strC  strD 
  <dbl> <dbl> <chr> <chr>
1     1    NA 0     Yes  
2    NA     2 1.2   Yes  
3     3     3 NA    NA   
4     4     4 2.4   No

我们达到了预期的结果。 我希望这一切都有帮助:)

另一种选择是使用mutate_all将所有 0 replaceNA ,如下所示:

library(dplyr)
df <- data.frame(v1 = c(1,0,4,2),
                 v2 = c(3,1,0,0))
df
#>   v1 v2
#> 1  1  3
#> 2  0  1
#> 3  4  0
#> 4  2  0
mutate_all(df, ~replace(., .==0, NA))
#>   v1 v2
#> 1  1  3
#> 2 NA  1
#> 3  4 NA
#> 4  2 NA

reprex 包于 2022-07-10 创建 (v2.0.1)

暂无
暂无

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

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