2017-10-18 6 views
0

Je souhaite normaliser les colonnes sélectionnées d'une trame de données par une normalisation définie par l'utilisateur. Jusqu'ici je vais avecComment passer une tranche de données à une fonction d'histogramme pour la normalisation de mode dans R?

library(tidyr) 
library(ggplot2) 

Mode <- function(x, na.rm = TRUE) { 
    x <- lapply(x, as.numeric) 
    distribution <- hist(x, breaks = 50, plot = FALSE) 
    distribution$mids[which.max(distribution$counts)] 
} 

data_normalised <- lapply(mtcars[,-9:-12], function(x) {(x-Mode(x))/(sd(x))}) 

comme exemple minimal. Cependant, hist se plaint que "x doit être numérique". Je pensais que cela pourrait être résolu par coulée

x <- lapply(x, as.numeric) 

qui ne fonctionne pas. Je sais que hist travaille pour

hist(mtcars[[3]]) 

mais je ne peux pas trouver un moyen de combiner le découpage df et la fonction hist, comme

hist(mtcars[[-9:-12]]) 

ne fonctionnera pas huitard.

Idéellement, je voudrais que la fonction Mode() fonctionne comme la fonction sd(). Prenez une colonne df et redonnez une valeur.

Merci pour votre aide!

+0

Votre fonction 'Mode' ne renvoie rien; vous devriez ajouter 'return() 'et la valeur qui vous intéresse, avant de terminer la fonction. – R18

Répondre

0

Dans votre Mode() fonction, class(x) est 'numeric' (c'est-à-dire que vous avez un vecteur numérique de longueur 32). Ensuite, vous utilisez lapply() pour appliquer la fonction as.numeric() à x. Après cette étape, class(x) est 'list' Depuis as.numeric est vectorisé, vous ne fait pas la boucle à travers les éléments du vecteur, au contraire, vous pouvez simplement utiliser x <- as.numeric(x) dans la fonction Mode:

Mode <- function(x, na.rm = TRUE) { 
    x <- as.numeric(x) 
    distribution <- hist(x, breaks = 50, plot = FALSE) 
    distribution$mids[which.max(distribution$counts)] 
} 

Vous pouvez alors procéder comme vous avez fait et il ne produira pas d'erreurs:

data_normalised <- lapply(mtcars[,-9:-12], function(x) {(x-Mode(x))/(sd(x))}) 

Si vous voulez obtenir un nouveau data.frame, vous pouvez utiliser cbind():

data_normalised <- do.call("cbind", data_normalised) 

Et vous obtenez:

head(data_normalised) 
      mpg   cyl  disp   hp  drat   wt  qsec   vs 
[1,] 0.9540484 -1.09187321 0.6858229 0.03646289 1.54298263 -0.84827399 -0.35815351 -0.01984063 
[2,] 0.9540484 -1.09187321 0.6858229 0.03646289 1.54298263 -0.58765969 -0.04476919 -0.01984063 
[3,] 1.2527070 -2.21174317 0.2662607 -0.21148473 1.44946853 -1.15487905 0.84501845 1.96422286 
[4,] 1.0204170 -1.09187321 1.4765365 0.03646289 0.00935141 -0.24017396 1.30949879 1.96422286 
[5,] 0.5724290 0.02799675 2.2995240 0.98449790 0.14027115 -0.01022017 -0.04476919 -0.01984063 
[6,] 0.4728762 -1.09187321 1.2102758 -0.03646289 -0.58913882 0.01022017 1.74599838 1.96422286 
+0

Fonctionne bien! Je vous remercie! Problème, je n'ai pas compris certains concepts sous-jacents ici. Je pense que le lappy donne déjà un dataframe. – Neudrino