2017-10-16 6 views
1

J'ai un long fichier cadre comme ce qui suit:R: Meilleure comparaison match

df <- structure(list(Date =c("2011-01", "2011-08", "2012-03", "2011-01", "2011-08", "2011-01", "2011-08", "2011-01", "2011-08", 
        "2011-01", "2011-08", "2012-03", "2011-01", "2011-08", "2011-01", "2011-08", "2011-01", "2011-08", 
        "2011-01", "2011-08", "2012-03", "2011-01", "2011-08", "2011-01", "2011-08", "2011-01", "2011-08"), 
    Part=c("A", "A", "A", "A", "A", "A", "A", "A", "A", 
      "B", "B", "B", "B", "B", "B", "B", "B", "B", 
      "C", "C", "C", "C", "C", "C", "C", "C", "C"), 
    method=c("Type1","Type1","Type1","Type2","Type2","Type3","Type3","Type4","Type4", 
       "Type1","Type1","Type1","Type2","Type2","Type3","Type3","Type4","Type4", 
       "Type1","Type1","Type1","Type2","Type2","Type3","Type3","Type4","Type4"), 
    value= c(4L, 46L, 43L, 9L, 8L, 46L, 63L, 84L, 2L, 5L, 78L, 2L, 89L, 2L, 6L, 62L, 25L, 46L, 3L, 4L, 7L, 24L, 13L, 21L, 19L, 8L, 3L)), 
    class= "data.frame", row.names=c(NA, -27L)) 

Je voudrais créer une autre colonne appelée BestMethod. La variable devrait être une liste de méthodes correspondant à la valeur la plus proche du type 3 par partie et par date. Par exemple, en 2011-01 pour la partie A, le type 1,2,3 a été appliqué et le type 1 était le plus proche du type 3. Sous BestMethod, j'aurais le type1. Sinon, si les 3 types n'étaient pas appliqués, je mettrais NA.

(Dans Excel, il peut ressembler à ceci:

=INDEX(C2:F2, MATCH(MIN(ABS(C2:F2-B2)), ABS(C2:F2-B2),0)) 

alors ceci:

=IF(B2="", "NA", INDEX($C$1:$F$1,1,(MATCH(H2,C2:F2,0))))) 

Je voudrais créer une autre colonne appelée FinalMethod Je voudrais avoir le type le plus indiqué. Par exemple, pour 2011-01, 2011-02 pour la partie A, le type 1 correspondait mieux, mais en 2011-03, le type 2 était le meilleur. tch. Dans ce cas, je voudrais que le type 1 soit le FinalMethod pour toutes les dates de cette partie.

J'ai essayé les éléments suivants:

which(abs(x-your.number)==min(abs(x-your.number))) 

mais je suis everying mal à appeler les valeurs de données correctes et l'exécuter à travers chaque ligne.

Merci.

sortie souhaitée:

df <- structure(list(Date =c("2011-01", "2011-08", "2012-03", "2011-01", "2011-08", "2011-01", "2011-08", "2011-01", "2011-08", 
        "2011-01", "2011-08", "2012-03", "2011-01", "2011-08", "2011-01", "2011-08", "2011-01", "2011-08", 
        "2011-01", "2011-08", "2012-03", "2011-01", "2011-08", "2011-01", "2011-08", "2011-01", "2011-08"), 
    Part=c("A", "A", "A", "A", "A", "A", "A", "A", "A", 
      "B", "B", "B", "B", "B", "B", "B", "B", "B", 
      "C", "C", "C", "C", "C", "C", "C", "C", "C"), 
    method=c("Type1","Type1","Type1","Type2","Type2","Type3","Type3","Type4","Type4", 
       "Type1","Type1","Type1","Type2","Type2","Type3","Type3","Type4","Type4", 
       "Type1","Type1","Type1","Type2","Type2","Type3","Type3","Type4","Type4"), 
    value= c(4L, 46L, 43L, 9L, 8L, 46L, 63L, 84L, 2L, 5L, 78L, 2L, 89L, 2L, 6L, 62L, 25L, 46L, 3L, 4L, 7L, 24L, 13L, 21L, 19L, 8L, 3L), 
    BestModel=c("Type2", "Type1", "NA", "Type2", "Type1", "Type2", "Type1", "Type2", "Type1", 
       "Type1", "Type1Type4", "NA", "Type1", "Type1Type4", "Type1", "Type1Type4","Type1", "Type1Type4", 
       "Type2", "Type2", "NA", "Type2", "Type2", "Type2", "Type2", "Type2", "Type2"), 
    FinalModel= c("Type1Type2", "Type1Type2","Type1Type2", "Type1Type2","Type1Type2", "Type1Type2","Type1Type2","Type1Type2","Type1Type2", 
        "Type1", "Type1", "Type1", "Type1", "Type1", "Type1","Type1", "Type1", "Type1", 
        "Type2", "Type2","Type2", "Type2", "Type2", "Type2","Type2", "Type2", "Type2")), 
    class= "data.frame", row.names=c(NA, -27L)) 
+0

La question est claire moi. Que signifie "plus proche du type 3"? Le type 3 n'est présent que pour les dates suivantes: 2013-08 et 2013-09 pour A, B et C, alors que les deux autres types ne le sont pas. Dans l'exemple, seul le type 1 est présent à la date 2011-01. Pourriez-vous rendre l'exemple et la sortie demandée un peu plus clairs? – missuse

+0

Salut! Merci d'avoir noté cela. J'ai changé les dates, donc il y a des chevauchements. Pour ceux sans Type3, je voudrais par défaut à NA. Exemple: Pour la partie A, si le type 1 est le plus proche du type 3 en 2011-01, imprimez le type 1 sous la colonne BestMethod. S'il n'y a pas de type 3, imprimez NA sous la colonne BestMethod. 2ème partie: Pour la partie A, si le nombre total de type 1 est supérieur au total de type 2 pour toutes les dates, imprimez le type 1 sous FinalMethod. Merci. – flightless13wings

+0

Pouvez-vous ajouter à la publication la sortie désirée? – Marcelo

Répondre

1

Une solution pas très élégante en utilisant dplyr + tidyr, mais fonctionne:

library(dplyr) 
library(tidyr) 

temp = df %>% 
    group_by(Part, Date) %>% 
    mutate(value.x = ifelse(method == "Type3", value, NA)) %>% 
    fill(value.x, .direction = "up") %>% 
    fill(value.x) %>% 
    mutate(difference = abs(value.x - value)) %>% 
    filter(method != "Type3") %>% 
    filter(difference == min(difference)) 

BestMethod = temp %>% 
    summarize(BestMethod = paste(method, collapse = " ")) 

FinalMethod = temp %>% 
    group_by(Part, method) %>% 
    summarize(count = n()) %>% 
    filter(count == max(count)) %>% 
    rename(FinalMethod = method) 

df %>% 
    full_join(BestMethod) %>% 
    full_join(FinalMethod) %>% 
    select(-count) %>% 
    arrange(Part, Date) 

Résultat:

 Date Part method value BestMethod FinalMethod 
1 2011-01 A Type1  4  Type2  Type1 
2 2011-01 A Type1  4  Type2  Type2 
3 2011-01 A Type2  9  Type2  Type1 
4 2011-01 A Type2  9  Type2  Type2 
5 2011-01 A Type3 46  Type2  Type1 
6 2011-01 A Type3 46  Type2  Type2 
7 2011-01 A Type4 84  Type2  Type1 
8 2011-01 A Type4 84  Type2  Type2 
9 2011-08 A Type1 46  Type1  Type1 
10 2011-08 A Type1 46  Type1  Type2 
11 2011-08 A Type2  8  Type1  Type1 
12 2011-08 A Type2  8  Type1  Type2 
13 2011-08 A Type3 63  Type1  Type1 
14 2011-08 A Type3 63  Type1  Type2 
15 2011-08 A Type4  2  Type1  Type1 
16 2011-08 A Type4  2  Type1  Type2 
17 2012-03 A Type1 43  <NA>  Type1 
18 2012-03 A Type1 43  <NA>  Type2 
19 2011-01 B Type1  5  Type1  Type1 
20 2011-01 B Type2 89  Type1  Type1 
21 2011-01 B Type3  6  Type1  Type1 
22 2011-01 B Type4 25  Type1  Type1 
23 2011-08 B Type1 78 Type1 Type4  Type1 
24 2011-08 B Type2  2 Type1 Type4  Type1 
25 2011-08 B Type3 62 Type1 Type4  Type1 
26 2011-08 B Type4 46 Type1 Type4  Type1 
27 2012-03 B Type1  2  <NA>  Type1 
28 2011-01 C Type1  3  Type2  Type2 
29 2011-01 C Type2 24  Type2  Type2 
30 2011-01 C Type3 21  Type2  Type2 
31 2011-01 C Type4  8  Type2  Type2 
32 2011-08 C Type1  4  Type2  Type2 
33 2011-08 C Type2 13  Type2  Type2 
34 2011-08 C Type3 19  Type2  Type2 
35 2011-08 C Type4  3  Type2  Type2 
36 2012-03 C Type1  7  <NA>  Type2 
+0

Nous vous remercions de votre solution. Y at-il un moyen de faire la même chose, mais pour plus de 3 types de méthodes? Mes données réelles ont 4 types de méthodes et je ne suis pas sûr de la façon de le faire sans utiliser votre instruction ifelse. – flightless13wings

+0

@ flightless13wings Dans ce cas, compareriez-vous '' "Type3" 'ou' "Type4" '? Le code ne devrait pas changer pour votre cas, sauf pour la référence 'Type'. Vous devriez publier les données réelles si mon code ne fonctionne pas pour ce que vous avez. – useR

+0

J'ai modifié les données pour inclure une 4ème méthode. La logique est la même que celle que vous avez utilisée dans votre solution seulement maintenant je comparerais Type1,2 et 4 à Type 3. Puis en sélectionnant celui qui se produit le plus pour la méthode finale. Je n'ai pas publié le fichier, car il est beaucoup trop volumineux et contient des informations confidentielles. J'espère que cet exemple de données imitera mieux le mien. Merci encore pour votre aide. – flightless13wings