2017-10-03 3 views
0

Je rencontre actuellement un hoquet où j'essaie de créer une table de valeurs à partir de certains calculs en amont. En règle générale, j'ai supposé qu'il y aurait au moins une valeur de 1 chaque fois que ces trames de données sont créées; mais je l'ai rencontré un exemple où cela n'a pas été le cas, et a fini avec une table qui ressemble à ceci:tryCatch() ou exists() dans R gestion des erreurs de la chaîne de tuyau

df <- data.frame(
    Experiment_Batch = c(rep("008_1", 83), 
         rep("008_6", 82), 
         rep("520_0", 2), 
         rep("944_10", 84), 
         rep("944_8", 85), 
         rep("944_9", 72)), 
    Overall = rep(0, 408) 
) 

Cela a provoqué le traitement en aval suivant:

df %>% 
    dplyr::count(Experiment_Batch, Overall) %>% 
    tidyr::spread(Overall, n, fill = 0) %>% 
    dplyr::select(Experiment_Batch, `1`) 

à l'erreur out: Error in overscope_eval_next(overscope, expr) : object '1' not found.

J'ai essayé d'utiliser tryCatch() et exists(), mais je n'arrive pas vraiment à les faire fonctionner correctement. Idéalement, tout cela serait manipulé avec élégance en utilisant des opérateurs de tuyauterie. Je sais déjà que je pourrais créer un objet et ajouter quelques déclarations d'if-else si nécessaire à mon flux de travail, mais je me demande s'il y a une façon «plus intéressante» de prendre soin de cela, donc je ne le ferais pas avoir à briser le travail.

Répondre

2

Vous pouvez utiliser certaines fonctions d'assistance si vous souhaitez ignorer la sélection si la colonne n'existe pas; Ici matches("^1$") essaiera de sélectionner la colonne dont le nom correspond exactement 1, puisque la trame de données n'a pas la colonne, il ignore simplement la sélection comme matches retours integer(0):

library(tidyverse) 
df %>% 
    count(Experiment_Batch, Overall) %>% 
    spread(Overall, n, fill = 0) %>% 
    select(Experiment_Batch, matches("^1$")) 

# A tibble: 6 x 1 
# Experiment_Batch 
#*   <fctr> 
#1   008_1 
#2   008_6 
#3   520_0 
#4   944_10 
#5   944_8 
#6   944_9 

matches retourne integer(0) lorsque non des noms de colonne correspond au motif qui est ignorée dans select:

matches("^1$", vars = c("0", "experiment")) 
# integer(0) 

matches("^1$", vars = c("0", "experiment", "1")) 
# [1] 3 

Si vous avez besoin de personnaliser la capture d'erreur:

library(tidyverse) 
df %>% 
    count(Experiment_Batch, Overall) %>% 
    spread(Overall, n, fill = 0) %>% 
    { 
     tryCatch(
      select(., Experiment_Batch, `1`), 
      error=function(e) select(., Experiment_Batch) 
     ) 
    } 
    # replace the error with the customized function to handle the exception 

# A tibble: 6 x 1 
# Experiment_Batch 
#*   <fctr> 
#1   008_1 
#2   008_6 
#3   520_0 
#4   944_10 
#5   944_8 
6   944_9