根据单词过滤一列,并对另外两列进行计算

时间:2019-03-12 05:55:49

标签: r string loops dplyr

如果这是一个重复的问题,请原谅。我进行了很长时间的搜索,但不能一次输入零。

我有一个数据集,其中有一个用于文本的列,另一个具有文本的第一个单词。

还有两列用于显示发送文本的人数和阅读文本的人数。

样本数据:

df <- data.frame(Word = c("Happy", "Good", "Have", "Do"), 
                 Text = c("Happy Birthday", "Good Morning", "Have a good day", 
                           "Do you have happy news"), 
                  Sent = c(10, 20, 15, 20), 
                  Read = c(8, 12, 9, 13), stringsAsFactors = FALSE)

我想计算每个单词的读取率。它是根据包含该单词的文字计算得出的

我尝试了以下代码,但似乎可以永远运行,尽管没有任何错误消息。

在我的情况下,我知道for循环对于18K记录而言效率不高,并且首选R中的高效解决方案。

感谢这方面的帮助。

for (i in 1:nrow(messages)){

  word <- messages$Word[i]
  messages$Rate[i] <- messages%>% filter(str_detect(string = Text, pattern = word)) %>% summarise(sum(Read)/sum(Sent))

}

enter image description here

1 个答案:

答案 0 :(得分:1)

使用基数R sapply的一种方法,对于每个Word,我们找出在数据帧中inds所在的索引(Word)。我们使用这些索引对sum ReadSent列进行子集并计算比率。

df$Rate <- with(df, sapply(Word, function(x) {
          inds = grep(paste0("\\b", x, "\\b"), Text, ignore.case = TRUE)
          sum(Read[inds])/sum(Sent[inds])
}))


df
#   Word                   Text Sent Read      Rate
#1 Happy         Happy Birthday   10    8 0.7000000
#2  Good           Good Morning   20   12 0.6000000
#3  Have        Have a good day   15    9 0.6285714
#4    Do Do you have happy news   20   13 0.6500000

如果您喜欢使用tidyverse的{​​{1}}方法

map_dbl

数据

library(tidyverse)
df %>%
   mutate(Ratio = map_dbl(Word, function(x) {
                   inds = str_detect(Text, fixed(x, ignore_case=TRUE))
                    sum(Read[inds])/sum(Sent[inds])
}))