【问题标题】:How to convert character vector into variable names and str_count?如何将字符向量转换为变量名和str_count?
【发布时间】:2019-09-01 01:14:19
【问题描述】:

我正在尝试通过针对文本数据帧执行 str_count 的函数将术语的字符向量转换为变量,但我不知道该怎么做。

给定一个向量:

variablenames <- c("strong","weak","happy","sad")

和一个文本数据框,例如:

library(tidyverse)
textdf <- as.data.frame("Happy was a dwarf who was perpetually sad.") %>% rename(text = 1)

认为我想要这样的东西:

countstring_fn <- function(variablenames,textdf){
for(term in variablenames){
paste0(term,"count") <- str_count(term,textdf)
}
}

但我很确定那是行不通的。预期的输出是:

text,strongcount,weakcount,happycount,sadcount
"Happy was a dwarf who was perpetually sad.",0,0,1,1

有没有人做过类似的事情并成功了?

【问题讨论】:

    标签: r tidyverse stringr


    【解决方案1】:

    这是另一种方式。

    library(tidyverse)
    variablenames <- c("strong", "weak", "happy", "sad")
    textdf <- tibble(
      text = c(
        '"Happy was a dwarf who was perpetually sad."',
        '"If you\'re strong, you\'re not weak."'
      )
    )
    textdf[, str_c(variablenames, 'count')] <- do.call(
      rbind, 
      lapply(
        textdf$text, 
        function(df) { 
          str_count(toupper(df), toupper(variablenames)) 
        }
      )
    )
    invisible(
      apply(
        textdf, 
        1, 
        function(vec) {
          cat(str_c(str_c(vec, collapse = ','), '\n'))
        }
      )
    )
    

    这里的主要区别在于 textdf 数据框中的字符串用双引号括起来(如果您从 .csv 导入数据,您可以调用 str_c('"', textdf$text, '"') 以获得相同的效果)。然后,我们将所有文本和模式转换为大写,以确保找到所有匹配项。最后,我们可以调用str_count() 来获取计数的整数向量,我们可以通过定义所需的列名将其单独分配给特定列。

    prntFunc 函数然后使用 apply() 将数据框中的每一行打印到控制台(矢量化比使用 for 循环更快):

    "Happy was a dwarf who was perpetually sad.",0,0,1,1
    "If you're strong, you're not weak.",1,1,0,0
    

    我们首先使用str_c(),因为它具有折叠能力。换句话说,我们可以将一行中所有五列中的字符串连接成一个字符串,其中,作为分隔符。然后,对于cat(),我们需要再次使用str_c() 在每个“行字符串”的末尾附加一个换行符(\n)。最后,我们可以调用cat(),在控制台中显示带有特殊字符的字符串,例如",不伴随转义字符(\)。 cat() 调用用 invisible() 包装,以抑制 NULL 在交互调用时附加到末尾的 cat()

    【讨论】:

      【解决方案2】:

      我们可以将text 转换为小写,并检查每个文本中variablenames 的出现,并返回一个逗号分隔的字符串。我们为每个 variablenames 添加单词边界 (\\b) 以避免将“sad”与“saddened”匹配。然后我们可以separate将数据放到不同的列中

      library(tidyverse)
      
      textdf %>%
         mutate(count = map_chr(tolower(text), function(x) 
          toString(map_int(paste0("\\b",variablenames,"\\b"), ~str_count(x, .x))))) %>%
        separate(count, into = paste0(variablenames, "_count"), sep = ",", convert = TRUE)
      
      #                                        text strong_count weak_count happy_count sad_count
      #1 Happy was a dwarf who was perpetually sad.            0          0           1         1
      

      【讨论】:

        【解决方案3】:
        # added second row to show output of function
        
        textdf <- structure(list(text = c("Happy was a dwarf who was perpetually sad.",
        "Sad was a dwarf who was perpetually sad.")), row.names = c(NA,
        -2L), class = "data.frame")
        
        # counting the occurrences of words in 'variablenames'
        
        pmap_df(
          textdf, function(text) {
            map(variablenames, ~ str_count(tolower(text), pattern = .)) %>%
            t %>% as.data.frame
          }
        ) %>%
          setNames(variablenames) %>%
          bind_cols(textdf, .)
        
        # Leaves you with a data frame with counts for each word as columns.
        
                                                text strong weak happy sad
        1 Happy was a dwarf who was perpetually sad.      0    0     1   1
        2   Sad was a dwarf who was perpetually sad.      0    0     0   2
        
        
        

        【讨论】:

          【解决方案4】:

          另一种方式:

          library(tidyverse)
          
          t(sapply(dat$strgs, str_count, pattern = coll(patts, T, 'en'))) %>%
            data.frame %>%
            set_names(., patts) %>%
            bind_cols(dat, .)
          
          #   strgs                                strength ignorance present future collapse
          # 1 War Is Peace, Freedom Is Slavery...  1        1         0       0      0
          # 2 Who controls the past controls t...  0        0         1       1      0
          # 3 The collapse of the USSR was the...  0        0         0       0      1
          

          数据:

          patts <- c("strength", "ignorance", "present", "future", "collapse")
          
          dat <- data.frame(
            strgs = c(
              "War Is Peace, Freedom Is Slavery, and Ignorance Is Strength.",
              "Who controls the past controls the future: who controls the present controls the past.",
              "The collapse of the USSR was the greatest geopolitical catastrophe of the century."
            )
          )
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-27
            • 2010-12-04
            • 2019-10-26
            • 2017-04-20
            相关资源
            最近更新 更多