You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用Ngram预测下一词报错:closure对象不可子集化

Fixing the "object of type 'closure' is not subsettable" Error in Your Ngram Predictor

Hey there! Let's tackle that frustrating error you're hitting with your next-word prediction functions for Shiny. The root causes are mostly incorrect empty-value checks and misusing return() inside ifelse—let's fix these issues one by one.

Key Issues in Your Code

  • Wrong empty output check: out == "character(0)" doesn't work because when no matches are found, as.character() returns a length-0 character vector, not the string "character(0)".
  • Misusing return() in ifelse: ifelse is a vectorized function, and putting return() inside it treats return as a closure (function object) instead of executing it, which triggers the subsettable error. We'll replace ifelse with standard if/else statements for clearer, error-free logic.
  • Minor dataframe handling bug: In the ngrams function, you're calling str_count(input, boundary("word")) on the dataframe instead of the text column.

Corrected Code

Let's rewrite each function with these fixes:

library(tidyverse)
library(stringr)
library(dplyr)
library(ngram)
library(tidyr)

# Load pre-built ngram tables
bi_words <- readRDS("./bi_words.rds")
tri_words <- readRDS("./tri_words.rds")
quad_words <- readRDS("./quad_words.rds")

bigram <- function(input_words){
  num <- length(input_words)
  out <- bi_words %>%
    dplyr::filter(word1 == input_words[num]) %>%
    top_n(1, n) %>%
    slice(1) %>%  # Simpler than filter(row_number() == 1L)
    select(num_range("word", 2)) %>%
    as.character()
  
  # Check if output is empty, return "?" if true
  if (length(out) == 0) {
    return("?")
  } else {
    return(out)
  }
}

trigram <- function(input_words){
  num <- length(input_words)
  out <- tri_words %>%
    dplyr::filter(word1 == input_words[num-1], word2 == input_words[num]) %>%
    top_n(1, n) %>%
    slice(1) %>%
    select(num_range("word", 3)) %>%
    as.character()
  
  # Fall back to bigram if no trigram match
  if (length(out) == 0) {
    return(bigram(input_words))
  } else {
    return(out)
  }
}

quadgram <- function(input_words){
  num <- length(input_words)
  out <- quad_words %>%
    dplyr::filter(word1 == input_words[num-2], word2 == input_words[num-1], word3 == input_words[num]) %>%
    top_n(1, n) %>%
    slice(1) %>%
    select(num_range("word", 4)) %>%
    as.character()
  
  # Fall back to trigram if no quadgram match
  if (length(out) == 0) {
    return(trigram(input_words))
  } else {
    return(out)
  }
}

ngrams <- function(input){
  input_df <- data.frame(text = input, stringsAsFactors = FALSE)
  replace_reg <- "[^[:alpha:][:space:]]*"
  
  input_clean <- input_df %>%
    mutate(text = str_replace_all(text, replace_reg, "")) %>%
    mutate(text = tolower(text))
  
  input_words <- unlist(str_split(input_clean$text, boundary("word")))
  input_count <- length(input_words)  # More direct than str_count
  
  # Choose the right ngram function based on word count
  out <- case_when(
    input_count == 1 ~ bigram(input_words),
    input_count == 2 ~ trigram(input_words),
    input_count >= 3 ~ quadgram(input_words),
    TRUE ~ "?"  # Fallback for empty input
  )
  
  return(out)
}

# Test the function
input <- "In case of a"
ngrams(input)

What Changed?

  1. Empty output check: Swapped out == "character(0)" for length(out) == 0 to correctly detect empty results.
  2. Replaced ifelse with if/else: This avoids the closure error and makes the fallback logic easier to read.
  3. Simplified row selection: Used slice(1) instead of filter(row_number() == 1L) for cleaner code.
  4. Fixed dataframe handling: In ngrams, we now target the text column explicitly and use length(input_words) instead of str_count for more reliable word count.
  5. Added fallback for empty input: The case_when includes a TRUE clause to return "?" if the input is empty.

Now your prediction functions should work without the closure error, and the fallback logic (quadgram → trigram → bigram → "?") will behave as expected.

内容的提问来源于stack exchange,提问作者Jayashree K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:12:29