Ich habe einen Datenrahmen mit Category und pd. Ich muss berechnen, wie oft jedes bedeutungsvolle Wort von allen pd in jedem Category gesehen wird. Ich bleibe beim letzten Schritt - der Zusammenfassung. Idealerweise wäre das Verhältnis dieser Frequenz zur Gesamtlänge von pd zu Category eine weitere X-Spalte.

Beispiel:

freq = structure(list(Category = c("C1", "C2"
), pd = c("96 oz, epsom salt 96 oz, epsom bath salt", 
          "17 x 24 in, bath mat")), .Names = c("Category", "pd"), row.names = c(NA, 
                                                                                -2L), class = "data.frame")

pool = sort(unique(gsub("[[:punct:]]|[0-9]","", unlist(strsplit(freq[,2]," ")))))
pool = pool[nchar(pool)>1]

freq:

    Category    pd
1   C1  96 oz, epsom salt 96 oz, epsom bath salt
2   C2  17 x 24 in, bath mat

pool:

[1] "bath"  "epsom" "in"    "mat"   "oz"    "salt" 

Gewünschte Ausgabe:

pool C1freq C1ratio C2freq C2ratio
bath 1 1/7 1 1/3
epsom 2 2/7 0 0
in 0 0 1 1/3
mat 0 0 1 1/3
oz 2 2/7 0 0
salt 2 2/7 0 0

Wo z.B. 7 ist die Länge von C1[,2] mit Zahlen, Interpunktion entfernt (wie in pool Regeln). 1/7 ist in dieser Form natürlich nicht erforderlich - hier soll nur die Nennerlänge angezeigt werden.

Wenn möglich, ohne dplyr oder qdap. Vielen Dank!!

1
Alexey Ferapontov 24 Dez. 2015 im 21:34

2 Antworten

Beste Antwort

Wir könnten es versuchen

library(qdapTools)
library(stringr)
lst <- str_extract_all(freq$pd, '[A-Za-z]{2,}')
m1 <- t(mtabulate(lst))
m2 <-  prop.table(m1,2)
cbind(m1, m2)[,c(1,3,2,4)]

Oder ohne das qdapTools,

 Un1 <- sort(unique(unlist(lst)))
 m1 <- do.call(cbind, lapply(lst, function(x)
            table(factor(x, levels=Un1))))
 colnames(m1) <- freq$Category
 cbind(m1, `colnames<-`(prop.table(m1,2), paste0(colnames(m1), 'Prop')))
2
akrun 25 Dez. 2015 im 06:20

Sie können Ihren aktuellen Ansatz folgendermaßen anpassen:

tab <- table(
  stack(
    setNames(
      lapply(strsplit(gsub("[[:punct:]]|[0-9]", "", freq$pd), "\\s+"), 
             function(x) x[nchar(x) > 1]), freq$Category)))

Beachten Sie hier, dass ich zuerst gsub und nicht nach dem Teilen verwendet habe. Dann teilte ich ein Leerzeichen auf und filterte die Daten auf die gleiche Weise, wie Sie sie gefiltert hatten. Schließlich habe ich setNames verwendet, damit ich stack verwenden kann, um ein langes data.frame zu erhalten, das tabellarisch aufgeführt werden kann.

Sobald die Daten tabellarisch aufgeführt sind, verwenden Sie einfach prop.table, um die gewünschte Ausgabe zu erhalten.

cbind(tab, prop.table(tab, 2))
#       C1 C2        C1        C2
# bath   1  1 0.1428571 0.3333333
# epsom  2  0 0.2857143 0.0000000
# in     0  1 0.0000000 0.3333333
# mat    0  1 0.0000000 0.3333333
# oz     2  0 0.2857143 0.0000000
# salt   2  0 0.2857143 0.0000000
1
A5C1D2H2I1M1N2O1R2T1 24 Dez. 2015 im 19:08