Search code examples
rn-gram

How to generate ngrams of each row of a dataframe so that each ngram creates a new row?


I try to generate ngrams from each row of my dataframe. They should be separated by "," .

The input looks like:

ID  Aufzeichnungen
1   vipr plus wurde gemacht, üz in behandlung
1   Röntgen der Hand, HCL aufgetragen
2   Hand wurde gemacht, Hand wurde betäubt

The output should look like:

ID Aufzeichnungen                                   ngram         
  <dbl> <chr>                                       <chr>         
1     1  vipr plus wurde gemacht, üz in behandlung  vipr plus wurde gemacht
2     1  vipr plus wurde gemacht, üz in behandlung  üz in behandlung 
3     1  Röntgen der Hand, HCL aufgetragen          Röntgen der Hand
4     1  Röntgen der Hand, HCL aufgetragen          HCL aufgetragen
5     2  Hand wurde gemacht, Hand wurde betäubt     Hand wurde gemacht
6     2  Hand wurde gemacht, Hand wurde betäubt     Hand wurde betäubt

So that every "," separates the ngrams and forms a new column with every ngram.

My code is:

PKV %>%
  group_by(ID) %>%
  group_modify(function(x, y) 
    tibble(Aufzeichnungen = x$Aufzeichnungen,
           ngram = ngram_asweka(x$Aufzeichnungen, sep = ",")))

There is a similar question but I don't know why but the code isn't working. An error occurs with "argument 'str' must be a single string".

I can't make just one single large row out of my data because it has to stay separated.

https://stackoverflow.com/questions/65225088/how-do-i-generate-ngrams-in-a-dataframe-so-that-each-ngram-creates-a-new-row

Thank you for your help!


Solution

  • This seems much more like "split strings at the ," than "make n-grams". Taking that approach:

    
    library(dplyr)
    library(tidyr)
    df %>%
      mutate(ngram = Aufzeichnungen) %>%
      separate_rows(ngram, sep = ", ", )
    # # A tibble: 6 × 3
    #      ID Aufzeichnungen                            ngram                  
    #   <int> <chr>                                     <chr>                  
    # 1     1 vipr plus wurde gemacht, üz in behandlung vipr plus wurde gemacht
    # 2     1 vipr plus wurde gemacht, üz in behandlung üz in behandlung       
    # 3     1 Röntgen der Hand, HCL aufgetragen         Röntgen der Hand       
    # 4     1 Röntgen der Hand, HCL aufgetragen         HCL aufgetragen        
    # 5     2 Hand wurde gemacht, Hand wurde betäubt    Hand wurde gemacht     
    # 6     2 Hand wurde gemacht, Hand wurde betäubt    Hand wurde betäubt 
    

    Alternately (and more string-splitty)

    df %>%
      mutate(ngram = strsplit(Aufzeichnungen, ", ")) %>%
      unnest(ngram)
    # for the same result
    

    Using this data:

    df = read.table(text = 'ID  Aufzeichnungen
    1   "vipr plus wurde gemacht, üz in behandlung"
    1   "Röntgen der Hand, HCL aufgetragen"
    2   "Hand wurde gemacht, Hand wurde betäubt"', header = T)