2017-08-03 83 views
0

的矢量I具有包含短字符串簡單的數據幀中的data.frame,其每一個都分配一個特定的類:填充基於令牌

datadb <- data.frame (
    Class = c('Class1', 'Class2', 'Class3'), 
    Document = c('This is test', 'Yet another test', 'A last test') 
) 

datadb$Document <- tolower(datadb$Document) 
datadb$Tokens <- strsplit(datadb$Document, " ") 

由此看來,我想建立包含另一個數據幀原來Class1列,但它已增加了對每個唯一標記一個新列,這樣的事情:

all_tokens <- unlist(datadb$Tokens) 
all_tokens <- unique(all_tokens) 

number_of_columns <- length(all_tokens) 
number_of_rows <- NROW(datadb) 

tokenDB <- data.frame(matrix(ncol=(1 + number_of_columns), nrow=number_of_rows)) 

names(tokenDB) <- c("Classification", all_tokens) 
tokenDB$Classification <- datadb$Class 

tokenDB然後將這個樣子:

Classification this is test yet another a last 
1   Class1 NA NA NA NA  NA NA NA 
2   Class2 NA NA NA NA  NA NA NA 
3   Class3 NA NA NA NA  NA NA NA 

如何通過原始數據框並向與已識別的每個向量相對應的新的tokenDB添加值?輸出應該如下所示:

Classification this is test yet another a last 
1   Class1 1 1  1  0  0  0 0 
2   Class2 0 0  1  1  1  0 0 
3   Class3 0 0  1  0  0  1 1 

輸出理想情況下應該是data.frame,但也可以是矩陣。

回答

2

使用tm包或真的任何其他文本挖掘軟件包來完成工作。我偏好tm。你正在創建的是一個文檔 - 術語矩陣。

library(tm) 
datadb <- data.frame (
    Class = c('Class1', 'Class2', 'Class3'), 
    Document = c('This is test', 'Yet another test', 'A last test') 
) 

corpus <- Corpus(VectorSource(datadb$Document)) 
dtm <- DocumentTermMatrix(corpus) 
dtm2 <- cbind(datadb$Class, as.matrix(dtm)) 
colnames(dtm2) <- c("Classification", colnames(dtm)) 
dtm2 
# Classification test this another yet last 
# 1    1 1 1  0 0 0 
# 2    2 1 0  1 1 0 
# 3    3 1 0  0 0 1 

這裏是只使用base

txt <- lapply(txt, function(x) data.frame(x, count = 1)) 
txt <- lapply(txt, function(x) data.frame(count = tapply(x$count, x$x, sum))) 
tdm <- Reduce(function(...) merge(..., all=TRUE, by="x"), 
       lapply(txt, function(x) data.frame(x=rownames(x), count=x$count))) 
rownames(tdm) <- tdm[, 1] 
dtm3 <- t(tdm[, -1]) 
dtm3[is.na(dtm3)] <- 0 
rownames(dtm3) <- paste("Doc", 1:3) 
dtm3 <- cbind(Classification=datadb$Class, dtm3) 
dtm3 
#  Classification is test This another Yet A last 
# Doc 1    1 1 1 1  0 0 0 0 
# Doc 2    2 0 1 0  1 1 0 0 
# Doc 3    3 0 1 0  0 0 1 1 
+0

您的建議感謝另一種方式 - 看起來這將最快/最簡單/乾淨達到期望的結果的方式。 – Ryan

+0

仍然好奇如何在沒有'tm'包的情況下做到這一點。 – Ryan

+0

剛剛發佈了一個選項,以基地爲準 – emilliman5

1
k=lapply(datadb$Tokens,match,all_tokens) 
    tokenDB[,-1]=t(mapply(function(x,y) {y[x]<-1;y[-x]<-0;y}, k,data.frame(t(tokenDB[,-1])))) 
    tokenDB 
    Classification this is test yet another a last 
1   Class1 1 1 1 0  0 0 0 
2   Class2 0 0 1 1  1 0 0 
3   Class3 0 0 1 0  0 1 1