Jest wiele postów dotyczących zastępowania wartości NA. Zdaję sobie sprawę, że w poniższej tabeli / ramce można zastąpić NA:
x[is.na(x)]<-0
Ale co, jeśli chcę ograniczyć to tylko do niektórych kolumn? Pokażę ci przykład.
Najpierw zacznijmy od zbioru danych.
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))
Co daje:
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
Ok, więc chcę ograniczyć zamianę tylko do kolumn „a” i „b”. Moja próba była:
x[is.na(x), 1:2]<-0
i:
x[is.na(x[1:2])]<-0
Co nie działa.
Moja próba z danymi.table, gdzie y<-data.table(x)
oczywiście nigdy nie zadziałała:
y[is.na(y[,list(a,b)]), ]
Chcę przekazać kolumny wewnątrz argumentu is.na, ale to oczywiście nie zadziała.
Chciałbym to zrobić w data.frame i data.table. Moim końcowym celem jest przekodowanie 1: 2 do 0: 1 w „a” i „b”, zachowując „c” taką, jaka jest, ponieważ nie jest to zmienna logiczna. Mam kilka kolumn, więc nie chcę tego robić po kolei. Chciałbym tylko wiedzieć, jak to zrobić.
Masz jakieś sugestie?
x[, 1:2][x[, 1:2] == 1] <- 0
x
przyjmuje macierz jako swojego pierwszego członka tylko podczas przypisywania? Czy ta funkcja jest gdzieś udokumentowana? Myślę też, że w drugim przykładzie zapomniałeś wstawić przecinek przed wektorami z nazwami kolumn.[
, wyodrębni określone kolumny (patrz stackoverflow.com/a/21137524/1201032 ). Mam nadzieję, że to odpowiada na twoje pytanie, ale w przyszłości unikaj komentowania bardzo starych odpowiedzi, takich jak ta; zamiast tego zadaj nowe pytanie.In both cases, 1:2 or c("a", "b") can be replaced by a pre-defined vector.
Kiedy użyłem predefiniowanego wektora takiego jak tenx[Vpredefined][is.na(x[Vpredefined])] <- 0
, daje mi to błądEdytuj 2020-06-15
Od
data.table
1.12.4 (październik 2019 r.)data.table
Zyskuje dwie funkcje, które to ułatwiają:nafill
isetnafill
.nafill
działa na kolumnach:cols = c('a', 'b') y[ , (cols) := lapply(.SD, nafill, fill=0), .SDcols = cols]
setnafill
działa na tabelach (wymiany odbywają się według referencji / na miejscu)setnafill(y, cols=cols, fill=0) # print y to show the effect y[]
Będzie to również bardziej wydajne niż inne opcje; zobacz
?nafill
więcej, wersjeNA
imputacji z ostatniej obserwacji przeniesionej do przodu (LOCF) i następnej obserwacji przeniesionej do tyłu (NOCB) dla szeregów czasowych.To zadziała dla twojej
data.table
wersji:for (col in c("a", "b")) y[is.na(get(col)), (col) := 0]
Alternatywnie, jak wskazuje David Arenburg poniżej, możesz użyć
set
(korzyść dodatkowa - możesz jej użyć nadata.frame
lubdata.table
):for (col in 1:2) set(x, which(is.na(x[[col]])), col, 0)
źródło
out <- x
aby uniknąć niezrozumienia z x data.frame z pytania? W przeciwnym razie jest to jeszcze krótsze polecenie:y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]
pomijanie nazwy zmiennej „out” i użycie „x”.Opierając się na odpowiedzi @Robert McDonald's
tidyr::replace_na()
, oto kilkadplyr
opcji kontrolowania, które kolumnyNA
są zastępowane: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))
źródło
Error in replace_na(., 0) : argument "value" is missing, with no default
. Jakieś sugestie co zmienić?Jest to teraz trywialne w tidyr dzięki replace_na (). Wygląda na to, że funkcja działa w przypadku data.tables oraz data.frames:
tidyr::replace_na(x, list(a=0, b=0))
źródło
Nie jestem pewien, czy jest to bardziej zwięzłe, ale ta funkcja również znajdzie i umożliwi zamianę NA (lub dowolnej wartości) w wybranych kolumnach tabeli danych:
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 }
Aby go zastosować:
y[update.mat(y, c("a", "b"), is.na(y))] <- 0
Funkcja tworzy macierz wybranych kolumn i wierszy (współrzędnych komórek), które spełniają kryteria wejściowe (w tym przypadku jest to.na == TRUE).
źródło
Możemy to rozwiązać za
data.table
pomocątidyr::repalce_na
funkcji ilapply
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")]
W ten sposób możemy również rozwiązać wklejanie kolumn
NA
ciągiem. Najpierw myreplace_na(x,"")
, a następnie możemy użyćstringr::str_c
do łączenia kolumn!źródło
W przypadku określonej kolumny istnieje alternatywa z
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
źródło
jest całkiem przydatne z {data.table} i {stringr}
library(data.table) library(stringr) x[, lapply(.SD, function(xx) {str_replace_na(xx, 0)})]
FYI
źródło
Zaczynając od data.table y, możesz po prostu napisać:
y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]
Nie zapomnij
library(data.table)
przed utworzeniemy
i uruchomieniem tego polecenia.źródło
to działa dobrze dla mnie
DataTable DT = new DataTable(); DT = DT.AsEnumerable().Select(R => { R["Campo1"] = valor; return (R); }).ToArray().CopyToDataTable();
źródło