web-dev-qa-db-ja.com

選択した列のテーブルのNA値を置換する方法

NA値の置換については多くの投稿があります。次の表/フレームのNAを次のものに置き換えることができることを認識しています。

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

動作しません。

y<-data.table(x)であるdata.tableの試みは明らかに動作しませんでした。

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

Is.na引数内に列を渡したいのですが、それは明らかに機能しません。

これをdata.frameとdata.tableで行いたいです。私の最終目標は、論理変数ではないため、「c」をそのままにしながら、「a」と「b」で1:2を0:1に再コーディングすることです。列がたくさんあるので、1つずつ実行したくありません。そして、私はこれを行う方法を知りたいだけです。

何か提案はありますか?

71
jnam27

できるよ:

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

以上(IMHO)、変数名を使用します。

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

どちらの場合も、1:2またはc("a", "b")は事前定義されたベクトルに置き換えることができます。

93
flodel

これはdata.tableバージョンで機能します:

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

または、David Arenburgが以下で指摘しているように、setを使用できます(副次的な利点-data.frameまたはdata.tableで使用できます)。

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

これは、現在、tidyrではreplace_na()を使用することで簡単になります。この関数は、data.tablesとdata.framesで機能するようです:

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

これがより簡潔かどうかはわかりませんが、この関数は、data.tableの選択された列でNA(または任意の値)の置換を検出して許可します。

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)を満たす選択した列と行(セル座標)のマトリックスを作成します。

1
Amy M

@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))
0
sbha

特定の列には、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
0
Rafa
We can solve it in data.table way with tidyr::repalce_na function and lapply
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")]

In this way,we can also solve paste cloumns with NA string.First, we replace_na(x,""),then we can use stringr::str_c to combine columns!
0
young Chen