如何替换所选列的表中的NA值

时间:2013-10-15 10:36:56

标签: r replace dataframe data.table na

有很多关于替换NA值的帖子。我知道可以用以下内容替换下表/框架中的NAs:

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

但是,如果我想将其限制为仅某些列,该怎么办?让我给你看一个例子。

首先,让我们从数据集开始。

set.seed(1234)
x <- data.frame(a=sample(c(1,2,NA), 10, replace=T),
                b=sample(c(1,2,NA), 10, replace=T), 
                c=sample(c(1:5,NA), 10, replace=T))

给出了:

    a  b  c
1   1 NA  2
2   2  2  2
3   2  1  1
4   2 NA  1
5  NA  1  2
6   2 NA  5
7   1  1  4
8   1  1 NA
9   2  1  5
10  2  1  1

好的,所以我只想将替换限制为列'a'和'b'。我的尝试是:

x[is.na(x), 1:2]<-0

x[is.na(x[1:2])]<-0

哪个不起作用。

我的data.table尝试,y<-data.table(x),显然永远不会起作用:

y[is.na(y[,list(a,b)]), ]

我想在is.na参数中传递列,但这显然不起作用。

我想在data.frame和data.table中执行此操作。我的最终目标是在'a'和'b'中将1:2重新编码为0:1,同时保持'c'的方式,因为它不是逻辑变量。我有一堆列,所以我不想一个接一个地做。而且,我只想知道如何做到这一点。

你有什么建议吗?

10 个答案:

答案 0 :(得分:88)

你可以这样做:

x[, 1:2][is.na(x[, 1:2])] <- 0

或更好(IMHO),使用变量名称:

x[c("a", "b")][is.na(x[c("a", "b")])] <- 0

在这两种情况下,1:2c("a", "b")都可以替换为预定义的矢量。

答案 1 :(得分:25)

这适用于您的data.table版本:

for (col in c("a", "b")) y[is.na(get(col)), (col) := 0]

或者,正如David Arenburg在下面指出的那样,您可以使用set(附带好处 - 您可以在data.framedata.table上使用它):

for (col in 1:2) set(x, which(is.na(x[[col]])), col, 0)

答案 2 :(得分:13)

现在使用replace_na()在tidyr中这是微不足道的。该函数似乎适用于data.tables以及data.frames:

tidyr::replace_na(x, list(a=0, b=0))

答案 3 :(得分:1)

不确定这是否更简洁,但此函数还将查找并允许在data.table的选定列中替换NAs(或您喜欢的任何值):

update.mat <- function(dt, cols, criteria) {
  require(data.table)
  x <- as.data.frame(which(criteria==TRUE, arr.ind = TRUE))
  y <- as.matrix(subset(x, x$col %in% which((names(dt) %in% cols), arr.ind = TRUE)))
  y
}

申请:

y[update.mat(y, c("a", "b"), is.na(y))] <- 0

该函数创建符合输入条件的所选列和行(单元格坐标)的矩阵(在本例中为is.na == TRUE)。

答案 4 :(得分:1)

我们可以使用data.table函数和tidyr::repalce_nalapply的方式解决问题

library(data.table)
library(tidyr)
setDT(df)
df[,c("a","b","c"):=lapply(.SD,function(x) replace_na(x,0)),.SDcols=c("a","b","c")]

这样,我们还可以解决带有NA字符串的粘贴列。首先,我们replace_na(x,""),然后可以使用stringr::str_c合并列!

答案 5 :(得分:0)

对于特定列,可以选择sapply

DF <- data.frame(A = letters[1:5],
             B = letters[6:10],
             C = c(2, 5, NA, 8, NA))

DF_NEW <- sapply(seq(1, nrow(DF)),
                    function(i) ifelse(is.na(DF[i,3]) ==
                                       TRUE,
                                       0,
                                       DF[i,3]))

DF[,3] <- DF_NEW
DF

答案 6 :(得分:0)

基于@Robert McDonald的tidyr::replace_na()答案,以下是一些dplyr选项,用于控制替换NA的列:

library(tidyverse)

# by column type:
x %>%
  mutate_if(is.numeric, ~replace_na(., 0))

# select columns defined in vars(col1, col2, ...):
x %>%
  mutate_at(vars(a, b, c), ~replace_na(., 0))

# all columns:
x %>%
  mutate_all(~replace_na(., 0))

答案 7 :(得分:0)

使用{data.table}和{stringr}非常方便

library(data.table)
library(stringr)

x[, lapply(.SD, function(xx) {str_replace_na(xx, 0)})]

仅供参考

答案 8 :(得分:0)

从data.table y开始,您只需编写:
y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]
创建library(data.table)并运行此命令之前,请不要忘记y

答案 9 :(得分:-4)

这对我来说很好

DataTable DT = new DataTable();

DT = DT.AsEnumerable().Select(R =>
{
      R["Campo1"] = valor;
      return (R);
}).ToArray().CopyToDataTable();