2015-12-01 15 views
11

Sto tentando di scrivere una funzione per contare il numero di istanze consecutive di un motivo. Per fare un esempio, mi piacerebbe la stringaConteggio di modelli consecutivi nelle stringhe usando R

string<-"A>A>A>B>C>C>C>A>A" 

da trasformare in

"3 A > 1 B > 3 C > 2 A" 

Ho una funzione che conta le istanze di ogni stringa, vedere di seguito. Ma non raggiunge l'effetto dell'ordine che mi piacerebbe. Qualche idea o suggerimento?

Grazie,

R

funzione esistente:

fnc_gen_PathName <- function(string) { 
p <- strsplit(as.character(string), ";") 
p1 <- lapply(p, table) 
p2 <- lapply(p1, function(x) { 
sapply(1:length(x), function(i) { 
    if(x[i] == 25){ 
    paste0(x[i], "+ ", names(x)[i]) 
    } else{ 
    paste0(x[i], "x ", names(x)[i]) 
    } 
}) 
}) 
p3 <- lapply(p2, function(x) paste(x, collapse = "; ")) 
p3 <- do.call(rbind, p3) 
return(p3) 
} 
+1

Avete visto la funzione 'rle()'? Dovrebbe funzionare bene se dividi la tua stringa in un vettore. – MrFlick

+0

Perfetto, grazie mille. Mai sentito parlare della funzione prima, ma molto facile da usare. –

risposta

10

Come commentato da @MrFlick si potrebbe provare il seguente utilizzando rle e strsplit

with(rle(strsplit(string, ">")[[1]]), paste(lengths, values, collapse = " > ")) 
## [1] "3 A > 1 B > 3 C > 2 A" 
0

Qui ci sono due dplyr soluzioni: una normale e una con rle. I vantaggi sono: può inserire più stringhe come un vettore, crea un set di dati intermedio ordinato prima (ugh) renesting.

library(dplyr) 
library(tidyr) 
library(stringi) 

strings = "A>A>A>B>C>C>C>A>A" 


data_frame(string = strings) %>% 
    mutate(string_split = 
      string %>% 
      stri_split_fixed(">")) %>% 
    unnest(string_split) %>% 
    mutate(ID = 
      string_split %>% 
      lag %>% 
      `!=`(string_split) %>% 
      plyr::mapvalues(NA, TRUE) %>% 
      cumsum) %>% 
    count(string, ID, string_split) %>% 
    group_by(string) %>% 
    summarize(new_string = 
       paste(n, 
        string_split, 
        collapse = " > ")) 

data_frame(string = strings) %>% 
    group_by(string) %>% 
    do(.$string %>% 
     first %>% 
     stri_split_fixed(">") %>% 
     first %>% 
     rle %>% 
     unclass %>% 
     as.data.frame) %>% 
    summarize(new_string = 
       paste(lengths, values, collapse = " > "))