2010-12-18 2 views
2

Supposons que nous créons un data.frame comme ceci:ifelse fonction imbriquée R passée à sapply() pour créer un nouveau data.frame

> hugs_per_day <- rnorm(10) 
> hugs_per_day <- as.data.frame(hugs_per_day) 
> hugs_per_day 
    hugs_per_day 
1 -2.500457495 
2 -0.204545274 
3 -0.955424927 
4 0.320184701 
5 1.822908001 
6 -0.058679520 
7 -0.276004919 
8 0.175341993 
9 -0.137404974 
10 0.005096691 

Et nous voulons exécuter une fonction chaque jour pour retourner une valeur basée sur les résultats, quelque chose comme ceci:

nested_ifelse <- function(x){ 

ifelse (x > 1,  mood <- "happy", 
    ifelse(x < 0, mood <- "sad", 
        mood <- "same as yesterday")) 

    return(mood) 
} 

l'exemple nested_ifelse() fait ce que je veux et je suis sapply sûr() est la fonction R correcte pour remplir une nouvelle colonne avec les résultats de la fonction, mais je Je ne peux pas mettre les deux ensemble.

Répondre

2

nested_ifelse devrait ressembler à ceci:

nested_ifelse <- function(x){ 
    mood <- ifelse (x > 1, "happy", 
    ifelse(x < 0, "sad", 
    "same as yesterday")) 
    return(mood) 
} 

ou plus simplement,

nested_ifelse <- function(x) 
    ifelse (x > 1, "happy", 
    ifelse(x < 0, "sad", 
    "same as yesterday")) 

et vous pouvez utiliser comme ceci:

d$mood2 <- sapply(d$v, nested_ifelse) 

mais en fait, vous n » t besoin d'appeler sapply ici:

d$mood <- nested_ifelse(d$v) 

est suffisant.

données

d devrait être comme ça ...

d <- data.frame(v=rnorm(10)) 
+0

Pour mon approche (qui peut ne pas être idéale), c'est parfait. Merci. – Milktrader

2

Vous n'avez pas utilisé set.seed si l'exemple n'est pas reproductible, mais cela devrait vous donner le vecteur demandé:

hugs_per_day$mood <- c("sad","same as yesterday","happy")[ 
       findInterval( hugs_per_day$hugs_per_day, c(-Inf, 0, 1)) ] 
    hugs_per_day 
     hugs_per_day    mood 
    1  0.5747557 same as yesterday 
    2 -1.0236557    sad 
    3 -0.0151383    sad 
    4 -0.9359486    sad 
    5  1.1022975    happy 
    6 -0.4755931    sad 
    7 -0.7094400    sad 
    8 -0.5012581    sad 
    9 -1.6290935    sad 
    10 -1.1676193    sad 
+0

pouvez-vous utiliser la fonction échantillon nested_ifelse() à la place de findInterval()? C'est le danger de trop généraliser une question, je suppose. Il semble que findInterval() arrive à une solution, mais que se passe-t-il si un autre vecteur a été introduit pour la comparaison? Par exemple, au lieu de x> 1, cela fonctionnerait-il pour x [, 1]> x [, 2]? Il peut y avoir des fois qu'une fonction spéciale est nécessaire, et dans ces cas, comment passeriez-vous cette fonction à sapply()? – Milktrader

+0

Oui, vous pouvez utiliser 'ifelse' imbriqué, mais ils sont limités à 7 profondément dans l'imbrication. Il y a beaucoup moins de code pour ajouter des éléments aux vecteurs de sélection, que pour ajouter des niveaux d'imbrication avec des clauses 'ifelse'. Vous ajoutez simplement un nouvel élément au premier vecteur et un nouvel élément au vecteur findInterval pour chaque nouveau niveau. –

+0

Merci pour une nouvelle méthode à prendre en compte. – Milktrader

0

Je ne sais pas si cela fonctionnera pour votre problème réel, mais je J'ai pensé que vous ne devez pas toujours nicher ifelse fonctions. Parfois, vous pouvez les utiliser de manière séquentielle, assurez-vous juste que la commande est correcte afin de ne pas écraser les valeurs précédentes.

set.seed(229) 
hugs_per_day <- data.frame(hugs=rnorm(10)) 

hugs_per_day$mood <- "same as yesterday" 
hugs_per_day$mood <- with(hugs_per_day, ifelse(hugs > 1, "happy", mood)) 
hugs_per_day$mood <- with(hugs_per_day, ifelse(hugs < 0, "sad", mood)) 
+0

Merci Josh . Il est bon de savoir aborder un problème de plus d'une façon. – Milktrader

Questions connexes