2012-04-01 36 views
4

我正在寫一個R函數來查找有形對話中的形式統計(語言測量)。我使用openNLP的詞性標註器來標記單詞(令人驚歎的工具,但因爲它正在執行一些重要的工作而很慢)。無論如何,時間已經成爲這個功能的一個問題,我遇到了一個問題,我希望儘快完成。我開始思考錯綜複雜的術語,並且知道我需要一些集體組織思考這個問題。從標記向量列表中創建標記頻率的數據幀

我有向量與標籤列表中他們是這樣的:

G 
[[1]] 
[1] "MD" "DT" "NN" "VB" "VBG" "TO" "POS" 

[[2]] 
[1] "DT" "NN" "JJ" "RB" 

[[3]] 
[1] "RB" "TO" "PRP" 

[[4]] 
[1] "VBZ" "PRP" "VBG" "RB" "TO" "NN" 

[[5]] 
[1] "NN" "NN" 

對於每一個向量我要計算所有可能的標籤出現的頻率(零將被插入載體的不包含一個標籤),並生成如下數據幀結構:

DT JJ MD NN POS PRP RB TO VB VBG VBZ 
1 1 0 1 1 1 0 0 1 1 1 0 
2 1 1 0 1 0 0 1 0 0 0 0 
3 0 0 0 0 0 1 1 1 0 0 0 
4 0 0 0 1 0 1 1 1 1 1 1 
5 0 0 0 2 0 0 0 0 0 0 0 

我已經把我的開始思考下面以及假數據集。我最初認爲要跟這張桌子一起去,但我不確定9,我知道這比說使用rlematch或索引[慢,如果任何這些可以使用。我也考慮過在這些向量上使用Reducemerge來做一個多合併,但知道R中的高階函數可能比其他方法慢(也許這可以用一些甜蜜的索引來完成)。

任何方式,我非常感謝這個問題的幫助。這兩個paremeters我要找的是:

  1. 底液
  2. 速度

的數據和我的初步想法(表可能是錯誤的路要走:

G <- list(c("MD", "DT", "NN", "VB", "VBG", "TO", "POS"), c("DT", "NN", 
"JJ", "RB"), c("RB", "TO", "PRP"), c("VBZ", "PRP", "VBG", "RB", 
"TO", "NN"), c("NN", "NN")) 

P <- lapply(G, function(x) table(sort(x))) #to get frequencies on each word 
sort(unique(names(unlist(P)))) #to get the column names and number 

道歉的線程名稱,因爲這是一個難分類。

編輯:(加替補打標效果)

非常有創意的答案。我甚至沒有考慮因素解決方案和指定級別。聰明。爲了提高速度,Joran的第二個答案是(我剛剛添加了列名,使用你已經創建了lev.mdsummer的迴應是最少的代碼,並且以速度與第二個綁定,我會按照Joran的第二個響應去做會讓我獲得最佳的速度提升,謝謝大家!十分讚賞:)可以作爲一個依據比較https://gist.github.com/trinker/91802b8c4ba759034881

 expr  min   lq  mean  median  uq  max neval 
    JORAN1() 648.04435 689.16756 714.9142 712.59122 732.4991 831.6623 100 
    JORAN2() 86.83879 92.91911 98.7068 97.44690 101.6764 177.4228 100 
    RINKER() 87.40797 94.07564 100.1154 98.39624 104.0887 177.3146 100 
     TIM() 900.65847 964.23419 993.9475 988.89306 1023.0587 1137.6263 100 
MDSUMMER() 1395.95920 1487.45279 1527.3181 1527.92664 1571.0997 1685.3298 100 
+1

爲標題,我會用「頻率」來代替「總和」。 – flodel 2012-04-01 02:15:02

+0

@ flodel良好的通話。完成。 – 2012-04-01 02:17:27

+0

作爲參考,可以很容易地重寫'splitstackshape ::: charMat'來處理這個問題。我正在「splitstackshape」的「stringi」分支中進行實驗。 – A5C1D2H2I1M1N2O1R2T1 2015-01-03 03:13:55

回答

5

我願意做任何這樣的:

lev <- sort(unique(unlist(G))) 

G1 <- do.call(rbind,lapply(G,function(x,lev){ table(factor(x,levels = lev, 
                ordered = TRUE))},lev = lev)) 

    DT JJ MD NN POS PRP RB TO VB VBG VBZ 
[1,] 1 0 1 1 1 0 0 1 1 1 0 
[2,] 1 1 0 1 0 0 1 0 0 0 0 
[3,] 0 0 0 0 0 1 1 1 0 0 0 
[4,] 0 0 0 1 0 1 1 1 0 1 1 
[5,] 0 0 0 2 0 0 0 0 0 0 0 

或更快的速度(但失去了列名):

G1 <- do.call(rbind,lapply(G,function(x,lev){ tabulate(factor(x,levels = lev, 
           ordered = TRUE),nbins = length(lev))},lev = lev)) 
1

這會給你以後的,但不知道它是否足夠快:

G <- list(c("MD", "DT", "NN", "VB", "VBG", "TO", "POS"), c("DT", "NN", 
      "JJ", "RB"), c("RB", "TO", "PRP"), c("VBZ", "PRP", "VBG", "RB", 
      "TO", "NN"), c("NN", "NN")) 
    Tags <- sort(unique(unlist(G))) 

    t(vapply(G,function(x){ 
     a <- Tags %in% x 
     a[a] <- tapply(x %in% Tags,x,sum) 
     a 
    }, FUN.VALUE = rep(0,length(Tags)))) 

     DT JJ MD NN POS PRP RB TO VB VBG VBZ 
    [1,] 1 0 1 1 1 0 0 1 1 1 0 
    [2,] 1 1 0 1 0 0 1 0 0 0 0 
    [3,] 0 0 0 0 0 1 1 1 0 0 0 
    [4,] 0 0 0 1 0 1 1 1 0 1 1 
    [5,] 0 0 0 2 0 0 0 0 0 0 0 
4

這就是你想要的我認爲,只需獲得唯一值的完整列表factor levels,然後根據每個向量作爲該因子的實例列表。

然後你可以用了整個事情了在do.call和行捆綁在一起:

levs <- sort(unique(names(unlist(P)))) 

do.call("rbind", lapply(G, function(x) table(factor(x, levs)))) 
+0

+1偉大的頭腦和所有的...... – joran 2012-04-01 01:56:51

+0

這個因素的使用是聰明:) +1 – 2012-04-01 01:57:52

+0

這是一個接近的事情,我想你7秒 - 我還沒有探討你是否使用有序是重要的 - 可能與新加坡那裏需要額外的照顧。 – mdsumner 2012-04-01 01:57:53

1

也許qdapToolsmtabulate將會很快在這裏:

library(qdapTools) 
mtabulate(G) 

## DT JJ MD NN POS PRP RB TO VB VBG VBZ 
## 1 1 0 1 1 1 0 0 1 1 1 0 
## 2 1 1 0 1 0 0 1 0 0 0 0 
## 3 0 0 0 0 0 1 1 1 0 0 0 
## 4 0 0 0 1 0 1 1 1 0 1 1 
## 5 0 0 0 2 0 0 0 0 0 0 0