调用ntoken处理VCorpus报错:如何获取各文档的token计数?
no applicable method for 'ntoken' Error with tm & quanteda Hey there! Let's sort out that error you're hitting with ntoken(). The root issue here is that you're mixing objects from two separate text analysis packages—tm and quanteda—and they don't natively recognize each other's structures.
Why the Error Happens
ntoken() is a function from the quanteda package, and it expects quanteda-specific objects (like quanteda::corpus or quanteda::tokens) as input. But you're passing a VCorpus object created with tm, which quanteda can't process directly—hence the "no applicable method" message.
Here are three straightforward ways to fix this and get your desired doc_length vector:
Option 1: Stick with quanteda (Recommended for Consistency)
If you can shift your workflow to use quanteda end-to-end, everything will work seamlessly since all functions are designed to play together:
library(quanteda) library(dplyr) library(stringi) # Your original data frame df <- structure(list(text = c("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. ", "Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. ", "Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc" )), .Names = "text", class = "data.frame", row.names = c(NA, -4L)) # Create a quanteda corpus directly from your text column qcorpus <- corpus(df$text) # Generate a document-term matrix if you still need it dtm <- dfm(qcorpus) # Get token counts for each document doc_length <- ntoken(qcorpus)
Option 2: Stay with tm (Calculate Lengths from the DTM)
If you want to keep using tm, you can calculate document lengths directly from your DocumentTermMatrix by summing the word frequencies per row:
library(tm) library(dplyr) library(stringi) library(quanteda) # Your existing code up to creating the DTM df <- structure(list(text = c("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. ", "Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. ", "Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc" )), .Names = "text", class = "data.frame", row.names = c(NA, -4L)) review_source <- VectorSource(df$text) corpus <- VCorpus(review_source) dtm <- DocumentTermMatrix(corpus) # Calculate total token count per document (includes repeated words) doc_length <- rowSums(as.matrix(dtm)) # If you want unique token counts instead, use this: # doc_length <- rowSums(as.matrix(dtm) > 0)
Option 3: Convert tm Corpus to quanteda Corpus
If you already have a tm VCorpus and want to use quanteda's ntoken(), you can directly convert the object—quanteda supports this natively:
library(tm) library(quanteda) # Assume you've already created your tm corpus (from your existing code) qcorpus <- corpus(corpus) # Now ntoken() works perfectly doc_length <- ntoken(qcorpus)
All three methods will give you the numeric vector doc_length with token counts for each of your documents. Choose the one that fits your existing workflow best!
内容的提问来源于stack exchange,提问作者HelenVcl

