2014-07-11 13 views
3

Supposons que j'ai le texte suivant:Lecture de textes en utilisant une fonction comme sprintf R

" 7.7597  4.7389  3.0058  0.0013" 

Je sais que c'est le format:

" %9.4f %9.4f %9.4f %9.4f" 

Je veux extraire les variables hors de celui-ci. Je veux quelque chose comme fonction sprintf/gettextf mais ne fait l'inverse:

??????(" %9.4f %9.4f %9.4f %9.4f", v1, v2, v3, v4) 

Comment puis-je faire cela? (Sans chargement des paquets, si possible)

La méthode peu fiable que j'utilise est en ce moment:

temp <- as.numeric(unlist(strsplit(" 7.7597  4.7389  3.0058  0.0013"," "))) 
temp[!is.na(temp)] 
+0

Que diriez-vous 'read.table (text =" 7,7597 4,7389 3.0058 0.0013 ")'? Pouvez-vous penser à des situations où cela pourrait échouer? – konvas

+0

@konvas Beaucoup mieux que ce que je fais actuellement. Cela fonctionnera pour ma situation actuelle. Mais je cherche une solution générale, comme celle qui peut lire trois lettres dans ceci: 'read.table (text = sprintf ("% 1s-% 1s-% 1s "," a "," c "," e ")) 'séparément. – HBat

+0

Ou 'read.fwf' pour lire des fichiers de" largeur fixe "(si les valeurs sont jamais exécutées ensemble). R les stockera tous comme un type "numérique" générique de toute façon. – MrFlick

Répondre

0

Pourquoi ne pas rendre votre méthode plus fiable, au lieu de chercher quelque chose qui ne peut exister.

> x <- " 7.7597  4.7389  3.0058  0.0013" 

> unlist(read.table(text = x, strip.white = TRUE), use.names = FALSE) 
# [1] 7.7597 4.7389 3.0058 0.0013 

> as.numeric(sapply(strsplit(x, "\\s+"), "[", -1)) 
# [1] 7.7597 4.7389 3.0058 0.0013 

> as.numeric(strsplit(x, "\\s+")[[1]])[-1] 
# [1] 7.7597 4.7389 3.0058 0.0013 

> library(stringr) 
> as.numeric(strsplit(str_trim(x), "\\s+")[[1]]) 
# [1] 7.7597 4.7389 3.0058 0.0013 

> as.numeric(str_extract_all(x, "[0-9][.][0-9]+")[[1]]) 
# [1] 7.7597 4.7389 3.0058 0.0013 
1

je ferais:

scan(text=" 7.7597  4.7389  3.0058  0.0013") 
#Read 4 items 
#[1] 7.7597 4.7389 3.0058 0.0013 

Il rapporte correctement NA s:

scan(text=" 7.7597 NA 4.7389  3.0058  0.0013") 
#Read 5 items 
#[1] 7.7597  NA 4.7389 3.0058 0.0013 

Il brise sur l'entrée malformé (non numérique). Ainsi, vous pouvez contrôler avec un tryCatch:

tryCatch(scan(text=" abc 7.7597 4.7389"), error= function(e) cat("Malformed input\n")) 
#Malformed input 

Sous le capot

Comment se fait scan obtient les flotteurs correctement? La fonction a un argument, what, pour définir le type de données que vous recherchez. Le paramètre par défaut est

scan(..., what=double()) 

Donc, il analyse assez bien les flottants requis dans la question. Quoi qu'il en soit, si vous changez vos besoins et à la recherche de différents types de données, essayez:

scan(text=" 7 4 3 0 ", what=integer()) 
#Read 4 items 
#[1] 7 4 3 0 

Comme d'habitude, vous pouvez vérifier la cohérence des données:

tryCatch(scan(text=" 1 2.3", what=integer()), error= function(e) cat("Non-integer value(s) passed!\n")) 
#Non-integer value(s) passed! 
Questions connexes