使用dplyr/tidyr - 根据条件汇总数据

3

问题 我试图使用dyplr和tidyr来实现一个输出表格(类似于列联表),该表格将此数据汇总为频率(例如,标题、描述和正负数的计数)。 我尝试了许多不同的方法,最接近的例子是在Using Tidyr/Dplyr to summarise counts of groups of strings上找到的。 但这并不完全符合我的要求。

示例数据 数据看起来有点像...

df <- data.frame( "story_title"=c(0.0,0.0,0.0,-1.0,1.0),
                  "story_description"=c(-0.3,-0.3,-0.3,0.5,0.3),
                  "story_body"=c(-0.3,0.2,0.4,0.2,0))

期望输出结果 输出结果应该类似于这样,显示每个故事部分的摘要频率...

                  Negative  Neutral  Positive 
story_title              1         3        1         
story_description        3         0        2
story_body               1         1        3

(为story_body编辑的总数-感谢Akrun)

尝试的方法

如果我没错的话,第一步将是使用gather来重新塑造数据,如下所示...

df <- df %>% gather(type,score,starts_with("story"))

> df 
      type score
1        story_title   0.0
2        story_title   0.0
3        story_title   0.0
4        story_title  -1.0
5        story_title   1.0
6  story_description  -0.3
7  story_description  -0.3
8  story_description  -0.3
9  story_description   0.5
10 story_description   0.3
11        story_body  -0.3
12        story_body   0.2
13        story_body   0.4
14        story_body   0.2
15        story_body   0.0

我认为这里需要使用 group_by 和 summarise 的组合,我已经尝试过...

df %>% group_by(sentiment) %>%
          summarise(Negative = count("sentiment_title"<0),
                    Neutral  = count("sentiment_title"=0),
                    Positive  = count("sentiment_title">0)
                   )

显然这种方法并没有起作用。

有人能提供一个dplyr/tidyr的解决方案吗(一个基础表格的答案也会很有用作为一个例子)?


我认为 story_body 应该是 1 1 3 - akrun
3个回答

2

请尝试

library(dplyr)
library(tidyr)
gather(df) %>% 
      group_by(key,value= sign(value))%>%
      tally()  %>% 
      mutate(ind= factor(value, levels=c(-1,0,1), 
                    labels=c('Negative', 'Neutral', 'Positive'))) %>% 
      select(-value) %>% 
      spread(ind, n, fill=0)

1
我喜欢“sign”的想法。我可能可以用它来缩短我的代码。 - Pierre L
这绝对不是我想象中那么简单的任务,而且同意 sign() 是一个很机智的小动作。 - BarneyC
@BarneyC 我会在我有空的时候更新一些解释。 - akrun

1
尝试使用cut对三个类别进行重新标记。然后,只需要使用gather融合数据,并使用dcast重新塑造'wide'。
library(tidyr)
library(reshape2)
df[] <- lapply(df, function(x) {cut(x, c(-Inf,-1e-4,0,Inf), c("Negative", "Neutral", "Positive"))})
dcast(gather(df), key~value)
#            key Negative Neutral Positive
#1       story_title        1       3        1
#2 story_description        3       0        2
#3        story_body        1       1        3

1

为什么不直接使用R原生的xtabs函数呢?

根据你的代码:

>df <- df %>% gather(type,score,starts_with("story"))
>df$movement<-ifelse(df$score ==0 ,"Neutral",ifelse(df$score < 0 ,"Negative","Positive"))
>xtabs(~df$type+df$movement)

                      df$movement
  df$type             Negative Neutral Positive
  story_title              1       3        1
  story_description        3       0        2
  story_body               1       1        3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接