Je souhaite éliminer les valeurs aberrantes supérieures ou inférieures à 2 écarts-types, pour de nombreuses variables ayant des noms similaires (trop nombreuses pour être spécifiées individuellement dans le code).Filtrer plusieurs colonnes de table de données R pour éliminer les valeurs aberrantes
library(data.table)
irisdt <- data.table(iris)
myCols <- grep("Sepal", colnames(irisdt), value=TRUE)
# This works if I specify one column,
# but I have too many columns to specify, so need to use grep approach.
irisdt[, Sepal.Length.Outlier := (scale(Sepal.Length) < -2 | scale(Sepal.Length) > 2)]
# This does not work
irisdt[, (myCols) := lapply(myCols, function(x) {(scale(x) < -2 | scale(x) > 2)})]
# This partially works, but changes in place
irisdt[, (myCols) := lapply(myCols, function(x) {(scale(irisdt[[x]]) < -2 | scale(irisdt[[x]]) > 2)})]
# How do I make new variables, for example "Sepal.Length.Outlier"?
myOutlierCols <- grep(".Outlier", colnames(irisdt), value=TRUE)
# How do I select rows matching multiple columns (&)?
irisdt[myOutlierCols=="FALSE"] # does not work
irisdt[, hasOutlier := lapply(myCols, myCols==TRUE)] # does not work
irisdt[hasOutlier=="FALSE"] # relies on line above, which doesn't work
peut-être une fonction peut prendre une colonne data.table et dépouiller des valeurs supérieures ou inférieures à un seuil de score z. Cela pourrait être utilisé avec lapply.
# This does not work
removeOutliers <- function(myColumn, cutoff = 3) {
lapply(myColumn, function (x) {
if (scale(myColumn[[x]]) < -cutoff | scale(myColumn[[x]]) > cutoff) {
x <- NA #specify individual value instead of column?
}
})
}
removeOutliers(irisdt[,Sepal.Length]) # for testing
trimmedIrisdt <- irisdt[,lapply(.SD, removeOutliers(.SD)), .SDcols = myCols] # could do by = grouping variable
# Once outliers are made NA, this would work:
trimmedIrisdt <- complete.cases(trimmedIrisdt)
Merci pour la réponse très concise et claire. C'est beaucoup mieux que l'approche que je voulais! –
J'essaie de le modifier pour remplacer toutes les valeurs abs (scale (x))> = 2 avec NA. Voici ma tentative (ne fonctionne pas): irisdt [, (myCols): = lapply (.SD, fonction (x) (si (as.logical (do.call (pmin, lapply (.SD, fonction (x) abs (échelle (x)) <= 2)))) {NA} else {x})) , .SDcols = myCols] –
Cela ne fonctionne pas non plus pour remplacer des cellules: irisdt [, (myCols): = lapply (.SD, fonction (x) {if (abs (échelle (x)) <= 2) {x} autre {NA}}), .SDcols = myCols]. Pourriez-vous expliquer le do.call (pmin, ...)? –