2016-03-29 1 views
0

J'essaie de faire une correspondance sur une liste mais je suis incapable d'obtenir une sorte de sortie de ma fonction. la boucle échoue à vec [3] c'est pourquoi j'ai utilisé trycatch. mais je suis toujours incapable d'obtenir des résultats dans la sortie de ma fonction. Je suis incapable de produire quoi que ce soit. pourrait également faire la même chose avec appliquer la famille?boucle sur un vecteur avec trycatch

J'essaie de faire correspondre loc à vec. vec [3] va échouer car il n'y a pas de correspondance.

vec=c('i am going to ooty corbett','i have to go to ooty', 'i have to go to manali') 
loc=c('ooty','corbett') 

out est le vecteur im essayant de construire pour les matches.

out=NULL 
res_m=function(x,y){ 
    out[i]=tryCatch(
     { 
      for(i in 1:length(y)){ 
       print(i) 
       x=tolower(x) 
       y=strsplit(y[i], " ")[[1]] 
       out[i]=intersect(x,y) 
      } 
     },error=function(cond) { 
      out[i]=NA 
     }, 
     finally=print("can do") 
    )  
    return(out[i]) 
} 
res=res_m(loc,vec) 

En utilisant ifelse, j'ai réussi à le faire fonctionner. mais quand même pourrait obtenir une solution hors de mon approche.

res=NULL 
out=NULL 

for (i in 1:length(y)) { 
    print(i) 
    x = tolower(x) 
    z = strsplit(y[i], " ")[[1]] 
    out = intersect(x,z) 
    if (length(out) == 0) { 
     res[i] = NA 
    }else{ 
     res[[i]] = out 
    } 
} 
+1

L'erreur est probablement parce que 'intersect' donne un vecteur 0 longueur qui est attribué "sortir". Donc, vous pouvez gérer ce cas avec un 'if/else' avant d'affecter. Alternativement, voir 'grepl (coller (loc, collapse =" | "), vec)' ou 'regmatches (vec, gregexpr (coller (loc, collapse =" | "), vec))' –

+0

@alexis_laz: ouais le vec [3] retournera null.that c'est pourquoi j'ai utilisé trycatch. Je vais essayer avec ifelse et l'autre aussi. mais je pense que l'utilisation de l'ensemble serait rapide. donc je pensais sur les lignes de famille d'application. Merci pour l'aide. –

+0

utilise 'if (length (...)) {} else {}'. Vous n'avez pas dit qu'il y avait une erreur, donc 'tryCatch' ne vous semble pas approprié. –

Répondre

1

Dans votre res_m vous n'initialisez pas "out" comme un objet approprié et, aussi, vous écrasez "y":

res_m = function(x, y) 
{ 
    out = vector("list", length(y)) 
    for(i in 1:length(y)) { 
     x = tolower(x) 
     yy = strsplit(y[i], " ")[[1]] 
     out[[i]] = intersect(x, yy)  
    } 

    return(out) 
} 
res_m(loc, vec) 
#[[1]] 
#[1] "ooty" "corbett" 
# 
#[[2]] 
#[1] "ooty" 
# 
#[[3]] 
#character(0) 

Vous pouvez déplacer tolower et strsplit de votre boucle:

res_m2 = function(x, y) 
{ 
    out = vector("list", length(y)) 
    x = tolower(x) 
    y = strsplit(y, " ") 
    for(i in seq_along(y)) out[[i]] = intersect(x, y[[i]]) 
    return(out) 
} 
res_m2(loc, vec) 
#[[1]] 
#[1] "ooty" "corbett" 
# 
#[[2]] 
#[1] "ooty" 
# 
#[[3]] 
#character(0) 

Ou utilisez lapply:

res_m3 = function(x, y) 
{ 
    x = tolower(x) 
    lapply(strsplit(y, " "), function(yy) intersect(x, yy)) 
} 
res_m3(loc, vec) 
#[[1]] 
#[1] "ooty" "corbett" 
# 
#[[2]] 
#[1] "ooty" 
# 
#[[3]] 
#character(0) 

Si vous avez de faire une erreur:

force_error = function(x, y) 
{ 
    out = vector("list", length(y)) 
    x = tolower(x) 
    y = strsplit(y, " ") 
    for(i in seq_along(y)) 
     tryCatch(expr = { out[i] = intersect(x, y[[i]]) }, 
       error = function(e) { 
        cat(sprintf("error in in 'i = %d'\n --> %s\n", i, e)) 
        out[i] <<- NA 
       }, 
       warning = function(w) { 
        cat(sprintf("warning in in 'i = %d'\n --> %s\n", i, w)) 
        out[i] <<- NA 
       }) 
    return(out) 
} 
force_error(loc, vec) 
#warning in in 'i = 1' 
# --> simpleWarning in out[i] = intersect(x, y[[i]]): number of items to replace is not a multiple of replacement length 
# 
#error in in 'i = 3' 
# --> Error in out[i] = intersect(x, y[[i]]): replacement has length zero 
# 
#[[1]] 
#[1] NA 
# 
#[[2]] 
#[1] "ooty" 
# 
#[[3]] 
#[1] NA 

Alternativement, vous pouvez utiliser

regmatches(vec, gregexpr(paste(loc, collapse = "|"), vec)) 
#[[1]] 
#[1] "ooty" "corbett" 
# 
#[[2]] 
#[1] "ooty" 
# 
#[[3]] 
#character(0) 
+0

Perfect anwser! Merci! J'ai fait beaucoup d'erreurs stupides ici. Votre réponse est très utile. –