2017-10-13 8 views
3

Je sais que ma question est un peu vague, alors j'ai un exemple de ce que j'essaie de faire.Dans R, comment est-ce que je place un texte autour de tous les mots d'une chaîne, mais d'un texte spécifique (de gauche à droite)? Itération et manipulation de cordes

input <- c('I go to school') 

#Output 
'"I " * phantom("go to school")' 
'phantom("I ") * "go" * phantom("to school")' 
'phantom("I go ") * "to" * phantom("school")' 
'phantom("I go to ") * "school"' 

J'ai écrit une fonction, mais je vais avoir beaucoup de mal à comprendre comment le rendre applicable aux chaînes avec un nombre différent de mots et je ne peux pas comprendre comment je peux inclure itération à réduire le code copié. Il génère cependant la sortie ci-dessus.

Actuellement, ma fonction ne fonctionne que sur des chaînes de 4 mots. Il comprend également aucune itération.

Mes questions principales sont: Comment puis-je inclure l'itération dans ma fonction? Comment puis-je le faire fonctionner pour n'importe quel nombre de mots?

add_phantom <- function(stuff){ 
    strings <- c() 
    stuff <- str_split(stuff, ' ') 
    strings[1] <- str_c('"', stuff[[1]][[1]], ' "', ' * ', 
       'phantom("', str_c(stuff[[1]][[2]], stuff[[1]][[3]], stuff[[1]][[4]], sep = ' '), '")') 


    strings[2] <- str_c('phantom("', stuff[[1]][[1]], ' ")', 
         ' * "', stuff[[1]][[2]], '" * ', 
         'phantom("', str_c(stuff[[1]][[3]], stuff[[1]][[4]], sep = ' '), '")') 

    strings[3] <- str_c('phantom("', str_c(stuff[[1]][[1]], stuff[[1]][[2]], sep = ' '), ' ")', 
         ' * "', stuff[[1]][[3]], '" * ', 
         'phantom("', stuff[[1]][[4]], '")') 

    strings[4] <- str_c('phantom("', str_c(stuff[[1]][[1]], stuff[[1]][[2]], stuff[[1]][[3]], sep = ' '), ' ")', 
         ' * "', stuff[[1]][[4]], '"') 
    return(strings) 
}     

Répondre

0

c'est un travail de boucher, mais il donne le résultat attendu :):

input <- c('I go to school') 
library(purrr) 
inp   <- c(list(NULL),strsplit(input," ")[[1]]) 
phantomize <- function(x,leftside = T){ 
if(length(x)==1) return("") 
if(leftside) 
    ph <- paste0('phantom("',paste(x[-1],collapse=" "),' ") * ') else 
    ph <- paste0(' * phantom("',paste(x[-1],collapse=" "),'")') 
ph 
} 
map(1:(length(inp)-1), 
    ~paste0(phantomize(inp[1:.x]), 
      inp[[.x+1]], 
      phantomize(inp[(.x+1):length(inp)],F))) 

# [[1]] 
# [1] "I * phantom(\"go to school\")" 
# 
# [[2]] 
# [1] "phantom(\"I \") * go * phantom(\"to school\")" 
# 
# [[3]] 
# [1] "phantom(\"I go \") * to * phantom(\"school\")" 
# 
# [[4]] 
# [1] "phantom(\"I go to \") * school" 
0

C'est un peu un hack, mais je pense qu'il se ce que vous essayez de faire:

library(corpus) 
input <- 'I go to school' 
types <- text_types(input, collapse = TRUE) # all word types 
(loc <- text_locate(input, types)) # locate all word types, get context 
## text    before    instance    after    
## 1 1          I  go to school     
## 2 1         I  go  to school      
## 3 1        I go  to  school       
## 4 1       I go to school      

La valeur de retour est une trame de données, avec des colonnes de type corpus_text. Cette approche semble fou, mais il n'alloue pas réellement de nouvelles chaînes pour les before et after contextes (qui ont tous deux de type corpus_text)

Voici la sortie que vous vouliez:

paste0("phantom(", loc$before, ") *", loc$instance, "* phantom(", loc$after, ")") 
## [1] "phantom() *I* phantom(go to school)" 
## [2] "phantom(I) *go* phantom(to school)" 
## [3] "phantom(I go) *to* phantom(school)" 
## [4] "phantom(I go to) *school* phantom()" 

Si vous voulez vraiment devenir fou et ignorer la ponctuation:

phantomize <- function(input, ...) { 
    types <- text_types(input, collapse = TRUE, ...) 
    loc <- text_locate(input, types, ...) 
    paste0("phantom(", loc$before, ") *", loc$instance, "* phantom(", 
      loc$after, ")") 
} 

phantomize("I! go to school (?)...don't you?", drop_punct = TRUE) 
## [1] "phantom() *I* phantom(! go to school (?)...don't you?)" 
## [2] "phantom(I!) *go* phantom(to school (?)...don't you?)" 
## [3] "phantom(I! go) *to* phantom(school (?)...don't you?)" 
## [4] "phantom(I! go to) *school* phantom((?)...don't you?)" 
## [5] "phantom(I! go to school (?)...) *don't* phantom(you?)" 
## [6] "phantom(I! go to school (?)...don't) *you* phantom(?)" 
0

je suggère quelque chose comme ça

library(tidyverse) 
library(glue) 

test_string <- "i go to school" 

str_split(test_string, " ") %>% 
    map(~str_split(test_string, .x, simplify = T)) %>% 
    flatten() %>% 
    map(str_trim) %>% 
    keep(~.x != "") %>% 
    map(~glue("phantom({string})", string = .x)) 

Cet extrait de code peut facilement être implémenté dans une fonction et retournera la sortie suivante.

[[1]] 
phantom(i) 

[[2]] 
phantom(i go) 

[[3]] 
phantom(i go to) 

[[4]] 
phantom(go to school) 

[[5]] 
phantom(to school) 

[[6]] 
phantom(school) 

je pourrais avoir mal interprété votre question - je ne suis pas tout à fait sûr si vous voulez vraiment la sortie d'avoir le même format que dans votre sortie exemplaire.