我正在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我知道这比使用rle
或match
或索引[
要慢,如果其中任何一个可以用过的。我还想过在这些向量上使用带有Reduce
的{{1}}进行多重合并,但是知道R中的高阶函数可能比其他方法慢(可能这可以通过一些甜的索引来完成)。
我非常感谢你对这个问题的帮助。我正在寻找的两个参数是:
数据和我最初的想法(表可能是错误的方式:
merge
为线程名称道歉,因为这个线程很难分类。
编辑:(增加了基准测试结果)
非常有创意的答案。我甚至没有考虑因子解决方案和指定水平。聪明。为了速度Joran的第二个回答风(我刚刚使用你已经创建的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
添加了列名.mdsummer的响应是最少的代码量,并且速度很高。我会选择Joran的第二个回应因为它会让我获得最佳的速度提升。谢谢大家!非常感谢:)比较可用作为要点https://gist.github.com/trinker/91802b8c4ba759034881
lev
答案 0 :(得分: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 :(得分:4)
这就是我想要的,只需获取factor levels
的唯一值的完整列表,然后根据每个向量作为该因子的实例制表。
然后你可以将整个事物包装在do.call中并将这些行绑定在一起:
levs <- sort(unique(names(unlist(P))))
do.call("rbind", lapply(G, function(x) table(factor(x, levs))))
答案 2 :(得分: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
答案 3 :(得分:1)
也许 qdapTools mtabulate
在这里会很快:
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