【发布时间】:2012-06-17 17:10:52
【问题描述】:
我有一个包含一些数字列的数据框。某些行的值为 0,在统计分析中应被视为空值。在R中将所有0值替换为NULL的最快方法是什么?
【问题讨论】:
-
我认为您不希望/可以用 NULL 值替换,但 NA 在 R 术语中用于此目的。
我有一个包含一些数字列的数据框。某些行的值为 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 替换零,即完全删除包含至少一个零的所有行。例如,当使用var、cov 或cor 时,这实际上相当于首先用NA 替换零并将use 的值设置为"complete.obs"。然而,这通常不能令人满意,因为它会导致额外的信息丢失。
2. 在解决方案中,我使用df == 0 向量化,而不是运行某种循环。 df == 0 返回(尝试一下)一个与df 大小相同的矩阵,其中包含TRUE 和FALSE 条目。此外,我们还可以将此矩阵传递给子集[...](参见?'[')。最后,虽然df[df == 0] 的结果非常直观,但df[df == 0] <- NA 给出了预期的效果似乎很奇怪。赋值运算符<- 确实并不总是那么聪明,并且不能以这种方式与其他一些对象一起工作,但它可以与数据帧一起工作;见?'<-'。
1 集合论中的空集感觉有些相关。
2 与集合论的另一个相似之处:空集是每个集的子集,但我们不为它保留任何空间。
【讨论】:
#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
【讨论】:
没有[<- 函数的替代方法:
一个样本数据框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
【讨论】:
您只能在数字字段中将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:5 替换为数据框中的列数,或者替换为 1:ncol(df)。
【讨论】:
1:ncol(df) 替换1:5。我不想让方程式过于复杂或难以阅读。
1:5 更改为您想要更改的列号,例如12:15,但如果您想确认它只会影响数字列,那么只需将if 语句中函数的第二行,如下所示:if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }.
让我假设您的 data.frame 是不同数据类型的混合体,并非所有列都需要修改。
仅修改第 12 到 18 列(总共 21 列),只需这样做
df[, 12:18][df[, 12:18] == 0] <- 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
【讨论】:
for (j in names(DT)); set(DT,which(DT[[j]] == 0),j,NA)。有关使用 data.table 查找和替换值的更详细讨论,请参阅 here。
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
【讨论】:
如果有人通过谷歌到达这里寻找对面(即如何将data.frame中的所有NA替换为0),答案是
df[is.na(df)] <- 0
或
使用 dplyr / tidyverse
library(dplyr)
mtcars %>% replace(is.na(.), 0)
【讨论】:
如果你和我一样,在想知道如何用 NA 替换数据框中的所有值时来到这里,那就是:
df[,] <- NA
【讨论】: