2013-03-24 13 views
5

se ho un vettoredeterminare la frequenza di stringa utilizzando grep

x <- c("ajjss","acdjfkj","auyjyjjksjj") 

e fare:

y <- x[grep("jj",x)] 
table(y) 

ottengo:

y 
     ajjss auyjyjjksjj 
      1   1 

Tuttavia la seconda stringa "auyjyjjksjj" dovrebbe contare la sottostringa "jj" due volte. Come posso cambiare questo da un calcolo vero/falso, per contare effettivamente la frequenza di "jj"?

Anche se per ciascuna stringa è possibile calcolare la frequenza della sottostringa divisa per la lunghezza della stringa, sarebbe ottimo.

Grazie in anticipo.

risposta

8

Ho risolto questo usando gregexpr()

x <- c("ajjss","acdjfkj","auyjyjjksjj") 
freq <- sapply(gregexpr("jj",x),function(x)if(x[[1]]!=-1) length(x) else 0) 
df<-data.frame(x,freq) 

df 
#   x freq 
#1  ajjss 1 
#2  acdjfkj 0 
#3 auyjyjjksjj 2 

E per l'ultima parte della domanda, calcolando frequenza/lunghezza della stringa ...

df$rate <- df$freq/nchar(as.character(df$x)) 

è nece ssary per convertire df $ x in una stringa di caratteri in quanto data.frame (x, freq) converte automaticamente le stringhe in fattori a meno che non si specifichi stringsAsFactors = F.

df 
#   x freq  rate 
#1  ajjss 1 0.2000000 
#2  acdjfkj 0 0.0000000 
#3 auyjyjjksjj 2 0.1818182 
+0

questo è eccellente, grazie. Mi accorgo che calcoli la lunghezza della stringa - nel data.frame posso chiamare la frequenza/lunghezza? questo sarebbe molto utile. Grazie. – brucezepplin

+0

oh scusa - cosa intendo dire, posso restituire per ogni stringa la frequenza della sottostringa divisa per la lunghezza della stringa? – brucezepplin

+0

scusate - I; sto ottenendo errore in nchar (df $ x): 'nchar()' richiede un vettore di caratteri – brucezepplin

7

Stai utilizzando lo strumento sbagliato. Prova gregexpr, che vi darà le posizioni in cui è stata trovata la stringa di ricerca (o -1 se non trovato):

> gregexpr("jj", x, fixed = TRUE) 
[[1]] 
[1] 2 
attr(,"match.length") 
[1] 2 
attr(,"useBytes") 
[1] TRUE 

[[2]] 
[1] -1 
attr(,"match.length") 
[1] -1 
attr(,"useBytes") 
[1] TRUE 

[[3]] 
[1] 6 10 
attr(,"match.length") 
[1] 2 2 
attr(,"useBytes") 
[1] TRUE 
+0

grazie mille, questo è stato molto utile. – brucezepplin

+0

la posizione è in realtà molto utile per me ora ci penso. Grazie. – brucezepplin

3

È possibile utilizzare qdap (anche se non in base installata R):

x <- c("ajjss","acdjfkj","auyjyjjksjj") 
library(qdap) 
termco(x, seq_along(x), "jj") 

## > termco(x, seq_along(x), "jj") 
## x word.count   jj 
## 1 1   1 1(100.00%) 
## 2 2   1   0 
## 3 3   1 2(200.00%) 

Si noti che l'uscita ha la frequenza e la frequenza rispetto al conteggio delle parole (l'uscita è in realtà una lista, ma stampa un bel produzione). Per accedere alle frequenze:

termco(x, seq_along(x), "jj")$raw 

## > termco(x, seq_along(x), "jj")$raw 
## x word.count jj 
## 1 1   1 1 
## 2 2   1 0 
## 3 3   1 2 
2

Questo semplice one-liner in base r si avvale di strsplit e poi Grepl, ed è abbastanza robusta, ma si rompa se deve contare partite come jjjjjj come 3 lotti di jj. Il pattern matching che rende possibile ciò è da @JoshOBriens excellent Q&A:

sum(grepl("jj" , unlist(strsplit(x , "(?<=.)(?=jj)" , perl = TRUE)))) 



# Examples.... 
f<- function(x){ 
    sum(grepl("jj" , unlist(strsplit(x , "(?<=.)(?=jj)" , perl = TRUE)))) 
    } 

    #3 matches here 
    xOP <- c("ajjss","acdjfkj","auyjyjjksjj") 
    f(xOP) 
    # [1] 3 

    #4 here 
    x1 <- c("ajjss","acdjfkj", "jj" , "auyjyjjksjj") 
    f(x1) 
    # [1] 4 

    #8 here 
    x2 <- c("jjbjj" , "ajjss","acdjfkj", "jj" , "auyjyjjksjj" , "jjbjj") 
    f(x2) 
    # [1] 8 

    #Doesn't work yet with multiple jjjj matches. We want this to also be 8 
    x3 <- c("jjjj" , "ajjss","acdjfkj", "jj" , "auyjyjjksjj" , "jjbjj") 
    f(x3) 
    # [1] 7 
+0

questo solleva un punto importante - la risposta accettata ha risolto questo problema. Se avessi "jjjjjj" vorrei restituire una frequenza di 3. Suppongo tuttavia che questo sarebbe un problema se permettessi sovrapposizioni nel conteggio delle frequenze dandomi una frequenza di 5. Per fortuna non è questo il caso! Ma grazie per averlo indicato. – brucezepplin

Problemi correlati