Votre cas de test n'est pas suffisamment complexe pour exposer quelques-uns des crocodiles rôdent dans la R concernant les objets de class == factor, options par défaut pour data.frame(), et l'utilisation de fonctions comme apply et ifelse. Je pourrais m'excuser pour la longueur de la réponse, mais c'est vraiment juste un petit sous-ensemble de ce que vous pouvez lire en The R Inferno. Disons que vous créez un data.frame, MRJF:
dfrm <-data.frame(textConnection("A B 2 12
L M 3 0
P Q 5 6", header=FALSE)
AVIS: Je modifié votre premier cas, un peu. Exécutez maintenant la première solution proposée: vous obtenez
apply(dfrm, 1, function(x){ifelse(x[3] > x[4], x[1], x[2])})
[1] "A" "L" "P"
Clairement 2 n'est PAS supérieur à 12, alors que s'est-il passé? La fonction apply fonctionne sur les matrices et a converti le data.frame en matrice avant de faire la fonction et testé "2"> "12" qui est TRUE. Donc, le crocodile # 1 est le comportement par défaut de apply().
erreurs ou avertissements résultent également de ce qui pourrait sembler au premier et deuxième coup d'œil pour être parfaitement raisonnable code R:
vector <- dfrm$V2;
vector[V3 > V4] <- V1[V3 > V4]
(Il n'a pas été un message d'erreur particulièrement instructif, pour moi en tout cas, ... quelque chose à propos de NA ... et c'était dû au fait que j'essayais d'assigner une valeur à un objet facteur pour lequel il n'y avait pas de niveau existant.) C'est le deuxième crocodile: la classe par défaut pour les valeurs de caractères données à la fonction data.frame est "facteur" plutôt que "caractère".
Le troisième crocodile est le comportement de ifelse:
with(dfrm, ifelse(V3 > V4, V1, V2))
[1] 1 2 3
WTF? La fonction ifelse convertit automatiquement les facteurs dans V1 et V2 en leurs représentations numériques internes et cela parce que la fonction contraint les valeurs retournées sur la base du type des arguments conditionnels. Pas la façon dont j'aurais conçu une telle fonction, mais ces choses ont été élaborées il y a des décennies, donc les changer est presque impossible.Ainsi, un couple de "droit", ou du moins plus sûr, les moyens de faire le travail que vous avez demandé: Method1:
with(dfrm, ifelse(V3 > V4, as.character(V1), as.character(V2)))
[1] "B" "L" "Q"
Method2:
vector <- as.character(dfrm$V2)
vector[which(dfrm$V3 > dfrm$V4)] <- as.character(dfrm$V1[which(dfrm$V3 > dfrm$V4)])
vector
[1] "B" "L" "Q"
'ifelse' est vectorisé donc' ifelse (df [[3]]> df [[4]], df [[1]], df [[2]]) 'est suffisant. – Marek
Parfait, merci! –