1
votes

Comment imbriquer des instructions ifelse pour tenir compte de trois conditions

J'ai un dataframe simple, mes données , avec deux variables, A et B . Voici un exemple des 100 premières lignes:

Error in ifelse(mydata$A < mydata$B, ((mydata$B - mydata$A)/(mydata$B -  : 
  unused arguments (0, ((mydata$A - mydata$B)/(100 - mydata$B)))

Je veux ajouter une nouvelle colonne pour la variable P , mais le calcul pour P diffère pour trois conditions. Telle que ...

Si A , alors P est égal à (B - A) / (B - 1)

Si A> B , alors P est égal à (A - B) / (100 - B)

Si A = B , alors P est égal à 0

Comment est-ce que j'applique cette logique? J'ai essayé d'utiliser une fonction ifelse imbriquée comme suit:

mydata$P <- ifelse(mydata$A < mydata$B, ((mydata$B-mydata$A)/(mydata$B - 1)), 
                ifelse(mydata$A == mydata$B), 0, 
                ((mydata$A-mydata$B)/(100 - mydata$B))) 

Mais elle renvoie cette erreur:

structure(list(A = c(0, 6, 35, 0, 99, 20, 3, 6, 80, 12, 23, 77, 
28, 80, 18, 90, 12, 60, 99, 90, 1, 3, 99, 100, 24, 99, 0, 40, 
0, 0, 99, 10, 23, 7, 99, 0, 76, 57, 99, 0, 21, 6, 0, 0, 0, 0, 
0, 0, 25, 50, 0, 100, 35, 40, 25, 90, 10, 20, 25, 100, 0, 15, 
98, 35, 85, 90, 0, 0, 90, 90, 90, 50, 45, 90, 20, 15, 85, 100, 
90, 15, 90, 85, 15, 25, 35, 90, 10, 35, 35, 100, 20, 0, 60, 100, 
19, 60, 0, 50, 50, 6), B = c(10, 14, 5, 25, 87, 12, 12, 5, 80, 
87, 60, 78, 23, 60, 18, 45, 12, 34, 99, 70, 2, 21, 50, 57, 50, 
70, 12, 18, 34, 34, 23, 45, 34, 12, 99, 29, 76, 34, 50, 12, 20, 
12, 50, 45, 2, 5, 12, 34, 25, 25, 25, 90, 45, 25, 35, 80, 15, 
15, 20, 80, 4, 45, 27, 15, 85, 20, 58, 25, 20, 58, 45, 45, 48, 
80, 25, 10, 80, 45, 25, 10, 45, 65, 45, 25, 35, 87, 10, 13, 25, 
45, 25, 15, 25, 85, 19, 40, 12, 45, 65, 10)), row.names = 52:151, class = "data.frame")


3 commentaires

ifelse (DF $ A == DF $ B) . un support qui s'est rendu au mauvais endroit


Désolé, il y avait une faute de frappe dans mon message. Bien que je ne sois pas sûr que cela corrige votre point. Pouvez-vous le vérifier à nouveau et peut-être clarifier ce que vous dites?


Il y a déjà une solution publiée. S'il te plaît vérifie le


3 Réponses :


2
votes

Voici une alternative:

mydata$ P <- with(mydata, 
     ifelse(A < B, (B - A)/(B - 1), 
            ifelse(A > B, (A - B)/(100 - B), 0)))


0 commentaires

2
votes

Voici une solution qui utilise case_when de dplyr , car je la trouve assez soignée pour structurer ce type de déclarations. Tout d'abord, je définis les données:

df
#>       A  B          P
#> 52    0 10 1.11111111
#> 53    6 14 0.61538462
#> 54   35  5 0.31578947
#> 55    0 25 1.04166667
#> 56   99 87 0.92307692
#> 57   20 12 0.09090909
#> 58    3 12 0.81818182
#> 59    6  5 0.01052632
#> 60   80 80 0.00000000
#> 61   12 87 0.87209302
#> 62   23 60 0.62711864
#> 63   77 78 0.01298701
#> 64   28 23 0.06493506
#> 65   80 60 0.50000000
#> 66   18 18 0.00000000
#> 67   90 45 0.81818182
#> 68   12 12 0.00000000
#> 69   60 34 0.39393939
#> 70   99 99 0.00000000
#> 71   90 70 0.66666667
#> 72    1  2 1.00000000
#> 73    3 21 0.90000000
#> 74   99 50 0.98000000
#> 75  100 57 1.00000000
#> 76   24 50 0.53061224
#> 77   99 70 0.96666667
#> 78    0 12 1.09090909
#> 79   40 18 0.26829268
#> 80    0 34 1.03030303
#> 81    0 34 1.03030303
#> 82   99 23 0.98701299
#> 83   10 45 0.79545455
#> 84   23 34 0.33333333
#> 85    7 12 0.45454545
#> 86   99 99 0.00000000
#> 87    0 29 1.03571429
#> 88   76 76 0.00000000
#> 89   57 34 0.34848485
#> 90   99 50 0.98000000
#> 91    0 12 1.09090909
#> 92   21 20 0.01250000
#> 93    6 12 0.54545455
#> 94    0 50 1.02040816
#> 95    0 45 1.02272727
#> 96    0  2 2.00000000
#> 97    0  5 1.25000000
#> 98    0 12 1.09090909
#> 99    0 34 1.03030303
#> 100  25 25 0.00000000
#> 101  50 25 0.33333333
#> 102   0 25 1.04166667
#> 103 100 90 1.00000000
#> 104  35 45 0.22727273
#> 105  40 25 0.20000000
#> 106  25 35 0.29411765
#> 107  90 80 0.50000000
#> 108  10 15 0.35714286
#> 109  20 15 0.05882353
#> 110  25 20 0.06250000
#> 111 100 80 1.00000000
#> 112   0  4 1.33333333
#> 113  15 45 0.68181818
#> 114  98 27 0.97260274
#> 115  35 15 0.23529412
#> 116  85 85 0.00000000
#> 117  90 20 0.87500000
#> 118   0 58 1.01754386
#> 119   0 25 1.04166667
#> 120  90 20 0.87500000
#> 121  90 58 0.76190476
#> 122  90 45 0.81818182
#> 123  50 45 0.09090909
#> 124  45 48 0.06382979
#> 125  90 80 0.50000000
#> 126  20 25 0.20833333
#> 127  15 10 0.05555556
#> 128  85 80 0.25000000
#> 129 100 45 1.00000000
#> 130  90 25 0.86666667
#> 131  15 10 0.05555556
#> 132  90 45 0.81818182
#> 133  85 65 0.57142857
#> 134  15 45 0.68181818
#> 135  25 25 0.00000000
#> 136  35 35 0.00000000
#> 137  90 87 0.23076923
#> 138  10 10 0.00000000
#> 139  35 13 0.25287356
#> 140  35 25 0.13333333
#> 141 100 45 1.00000000
#> 142  20 25 0.20833333
#> 143   0 15 1.07142857
#> 144  60 25 0.46666667
#> 145 100 85 1.00000000
#> 146  19 19 0.00000000
#> 147  60 40 0.33333333
#> 148   0 12 1.09090909
#> 149  50 45 0.09090909
#> 150  50 65 0.23437500
#> 151   6 10 0.44444444

Ensuite, j'applique case_when , comme ceci:

# Perform calculation
df$P <- with(df, 
          dplyr::case_when(
            A < B ~ (B - A)/(B - 1),
            A > B ~ (A - B)/(100 - B),
            A == B ~ 0 
            ))

qui donne

# Define data frame
df <- structure(list(A = c(0, 6, 35, 0, 99, 20, 3, 6, 80, 12, 23, 77, 
                     28, 80, 18, 90, 12, 60, 99, 90, 1, 3, 99, 100, 24, 99, 0, 40, 
                     0, 0, 99, 10, 23, 7, 99, 0, 76, 57, 99, 0, 21, 6, 0, 0, 0, 0, 
                     0, 0, 25, 50, 0, 100, 35, 40, 25, 90, 10, 20, 25, 100, 0, 15, 
                     98, 35, 85, 90, 0, 0, 90, 90, 90, 50, 45, 90, 20, 15, 85, 100, 
                     90, 15, 90, 85, 15, 25, 35, 90, 10, 35, 35, 100, 20, 0, 60, 100, 
                     19, 60, 0, 50, 50, 6), 
                     B = c(10, 14, 5, 25, 87, 12, 12, 5, 80, 
                     87, 60, 78, 23, 60, 18, 45, 12, 34, 99, 70, 2, 21, 50, 57, 50, 
                     70, 12, 18, 34, 34, 23, 45, 34, 12, 99, 29, 76, 34, 50, 12, 20, 
                     12, 50, 45, 2, 5, 12, 34, 25, 25, 25, 90, 45, 25, 35, 80, 15, 
                     15, 20, 80, 4, 45, 27, 15, 85, 20, 58, 25, 20, 58, 45, 45, 48, 
                     80, 25, 10, 80, 45, 25, 10, 45, 65, 45, 25, 35, 87, 10, 13, 25, 
                     45, 25, 15, 25, 85, 19, 40, 12, 45, 65, 10)), 
                row.names = 52:151, class = "data.frame")

Créé le 08/08/2019 par paquet reprex (v0.3.0)


0 commentaires

0
votes

Alternativement, vous pouvez éviter d'utiliser ifelse en premier lieu:

mydata$P <- with(mydata, abs(B - A) / ((A <= B) * (B - 1) + (A >= B) * (100 - B)))

NB: si A vaut B , le numérateur est zéro et le dénominateur est 99 indépendant de la valeur de B , il n'y aura donc aucun problème à essayer de diviser par zéro.


0 commentaires