선택한 열에 대한 테이블의 NA 값을 바꾸는 방법


82

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

작동하지 않습니다.

내 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'는 논리 변수가 아니기 때문에 그대로 유지하는 것입니다. 나는 많은 칼럼을 가지고 있으므로 하나씩하고 싶지 않습니다. 그리고이 작업을 수행하는 방법을 알고 싶습니다.

의견 있으십니까?

답변:


115

넌 할 수있어:

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")미리 정의 된 벡터로 대체 할 수 있습니다.


그게 일입니다. '1'을 검색하려면 어떻게해야합니까? 나는 그것을 바꾸려고 노력했지만 작동하지 못했습니다.
jnam27

5
: 아마 이런x[, 1:2][x[, 1:2] == 1] <- 0
flodel

@flodel 왜 데이터 테이블 x은 할당을 할 때만 첫 번째 멤버로 행렬을 받아들입니까? 이 기능이 어딘가에 문서화되어 있습니까? 또한 두 번째 예에서 열 이름이있는 벡터 앞에 쉼표를 넣는 것을 잊었다 고 생각합니다.
ChiseledAbs

@ChiseledAbs, 매트릭스 인덱싱 (예 : stackoverflow.com/a/13999583/1201032 참조)을 언급하고 있다고 생각 하지만 할당에 국한되지 않고 데이터를 추출하는 데 사용할 수도 있습니다. 누락 된 쉼표와 관련하여 : 아니요. Data.frame은 열 목록이므로에 단일 인수를 [사용하면 지정된 열이 추출됩니다 ( stackoverflow.com/a/21137524/1201032 참조 ). 이것이 귀하의 질문에 대한 답변을 희망하지만 앞으로 이와 같이 매우 오래된 답변에 대해서는 언급하지 마십시오. 대신 새 질문을 게시하십시오.
flodel

In both cases, 1:2 or c("a", "b") can be replaced by a pre-defined vector.이와 같이 미리 정의 된 벡터를 사용하면 x[Vpredefined][is.na(x[Vpredefined])] <- 0오류가 발생합니다
Rohit Saluja

30

2020-06-15 수정

이후 data.table1.12.4 OCT (2019 년), data.table이를 용이하게하는 두 가지 기능을 얻는다 : nafillsetnafill.

nafill 열에서 작동합니다.

cols = c('a', 'b')
y[ , (cols) := lapply(.SD, nafill, fill=0), .SDcols = cols]

setnafill 테이블에서 작동 (대체는 참조 / 제자리에서 발생)

setnafill(y, cols=cols, fill=0)
# print y to show the effect
y[]

이것은 또한 다른 옵션보다 더 효율적입니다. 자세한 내용 ?nafill은 시계열에 대한 대치의 LOCF (last-observation-carried-forward) 및 NOCB (Next-observation-carried-backward) 버전을 참조하십시오 NA.


이것은 귀하의 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)

감사합니다. for 루프없이 위의 작업을 수행 할 수있는 방법이 있는지 3 년 후 알고 싶습니까? data.table 팀이 더 간결하게 만들었을 것이라고 생각합니다. 감사.
info_seekeR

1
@info_seekeR 나는 더 간결의 방법을 알고하지 않습니다
EDDI

이것은 flodel이 선택한 답변보다 더 나은 솔루션입니다. Flodel의 접근 방식은 할당 연산자 <-를 사용하므로 불필요한 데이터 복사가 필요합니다.
Michael

@MichaelChirico 코멘트의 첫 부분 out <- x에서 질문의 x data.frame에 대한 오해를 피하기 위한 단계 를 추가 했 습니까? 그렇지 않으면 더 짧은 명령입니다 : y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]'out'변수 이름을 건너 뛰고 'x'를 사용합니다.
Yoann Pageaud

@MichaelChirico 맞아요! 나는 nafill ()에 대해 완전히 잊었다
Yoann Pageaud

21

@Robert McDonald의 tidyr::replace_na()답변 을 바탕으로 s가 대체 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))

1
이 함수를 사용하면 오류가 발생 Error in replace_na(., 0) : argument "value" is missing, with no default합니다.. 무엇을 변경해야하나요?
Tim M. Schendzielorz

17

이것은 이제 replace_na ()로 깔끔하게 정리되었습니다. 이 함수는 data.tables 및 data.frames에서 작동하는 것으로 보입니다.

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

2

이것이 더 간결한 지 확실하지 않지만이 함수는 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

우리는 그것을 해결할 수 data.table와 방법 tidyr::repalce_na기능과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")]

이런 식으로 우리는 또한 NA문자열로 붙여 넣기 열을 해결할 수 있습니다 . 먼저 열을 결합 replace_na(x,"")하는 stringr::str_c데 사용할 수 있습니다 !


1
제한적이고 즉각적인 도움을 제공 할 수있는이 코드 스 니펫에 감사드립니다. 적절한 설명은 크게이 문제에 대한 좋은 해결책이 왜 보여 장기적인 가치를 향상 것이고, 다른 유사한 질문을 미래의 독자들에게 더 유용 할 것입니다. 제발 편집 당신이 만든 가정 등 일부 설명을 추가 할 답변을.
SomePerformance

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

0

{data.table} 및 {stringr}와 함께 사용하면 매우 편리합니다.

library(data.table)
library(stringr)

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

참고로


0

data.table y에서 시작하면 다음과 같이 작성할 수 있습니다 .이 명령을 만들고 실행 하기 전에
y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]
잊지 마세요 .library(data.table)y


-4

이것은 나를 위해 잘 작동합니다

DataTable DT = new DataTable();

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

1
이 R입니까? C #처럼 보입니다
Chris McKelt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.