在R

时间:2018-05-24 04:37:02

标签: r regex dynamic nested data.table

我有一个data.table DT_words(大尺寸):

DT_words <- data.table(word = c('word1', 'word2', 'word3','word4'))

我有另一个data.table DT_strings,它包含一个包含大量字符串的列

DT_strings <- data.table(string = c('string1 made of word1', 'string2 made of word2 and word2 and word3 and word1ly', 'string3 made of word1 and word2'))

对于DT_word中的每个单词,我想计算DT_string中所有字符串中出现的总次数,并将该值保存为DT_word中的一列。 我正在使用for循环,它看起来很难看。

我尝试过使用lapply和mapply但无济于事,因为该函数需要内部输入。

这是for循环的单词(但它需要很长时间而且很难看)

require(stringr)

for (i in 1:nrow(DT_words))
{
   DT_words$word_count[i] <-  sum(str_count(DT_strings$string, 
                                  paste0(c("\\b("),paste(DT_words[i, .(word)]),c(")\\b"))))
}

我知道格式更像是一个data.frame但是因为我使用了一个循环,所以它并不重要,是吗? 无论如何,我想知道我是否可以在data.table中使用apply并摆脱这种丑陋。

欲望输出将是:

> DT_words
    word word_count
1: word1          2
2: word2          3
3: word3          1
4: word4          0

编辑:我编辑了DT_strings以包含更多单词匹配的例子。我只对匹配整个单词感兴趣,因此必须以某种方式包含正则表达式语法。

3 个答案:

答案 0 :(得分:1)

如果您的单词确实只是用空格分隔,我会将它们拆分为列,转换为长格式,然后运行与by = .EACHI结合的二进制连接,例如,使用您的数据:

library(data.table)
library(magrittr)                       
DT_strings[, tstrsplit(string, " ", fixed = TRUE)] %>% 
  melt(., measure.vars = names(.), na.rm = TRUE) %>%
  .[DT_words, on = .(value = word), .N, by = .EACHI]
#    value N
# 1: word1 2
# 2: word2 3
# 3: word3 1
# 4: word4 0

P.S。

我已经使用fixed = TRUE来提高速度,因为我认为每个单词之间总是有一个空格。如果空格数变化,则需要使用tstrsplit(string, "\\s+"),而这可能会更慢。

答案 1 :(得分:0)

这是使用 Spinner spinner = findViewById(R.id.spinner); Button button3 = findViewById(R.id.button3); ArrayList<String> listSPinner = new ArrayList<>(); listSPinner.add("1"); listSPinner.add("1"); listSPinner.add("1"); listSPinner.add("1"); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, listSPinner); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { spinner.performClick(); } }); 套件的解决方案。

tidyverse

不使用library(stringr) library(purrr) DT_words$word_count <- map_int(paste0("\\b", DT_words$word,"\\b"), ~ str_count(DT_strings$string, .x) %>% sum) 的替代方案:

purrr

答案 2 :(得分:0)

假设您所谓的字符串和单词来自自然语言,我建议以下基本R解决方案可能运行得更快。关键在于你必须将字符串中的不同单词分开,但很容易适应&#39; strsplit&#39;到其他分隔符。

s <- c('string1 made of word1', 'string2 made of word2 and word2 and word3', 'string3 made of word1 and word2')
w <- c('word1', 'word2', 'word3','word4')

z <- as.data.frame(table(unlist(strsplit(s,' '))))
z[z$Var1 %in% w,]

#   Var1 Freq
#7 word1    2
#8 word2    3
#9 word3    1