【问题标题】:grouping by category, counting, sum, and dividing at the same time - R按类别分组,同时计数、求和和除法 - R
【发布时间】:2019-03-05 13:07:49
【问题描述】:

我有这个数据框:

> set.seed(100)
> df <- data.frame(X1 = sample(c(1:7, NA), 10, replace=TRUE),
                 X2 = sample(c(1:7, NA), 10, replace=TRUE),
                 X3 = sample(c(1:7, NA), 10, replace=TRUE),
                 YY = sample(c("a","b"), 10, replace=TRUE),
                 stringsAsFactors = FALSE)

> df
   X1 X2 X3 YY
1   3  5  5  a
2   3 NA  6  b
3   5  3  5  a
4   1  4  6  b
5   4  7  4  b
6   4  6  2  b
7   7  2  7  a
8   3  3 NA  b
9   5  3  5  b
10  2  6  3  a

最终输出是这样的:

YY   X1     X2    X3
 a  -0.25  -0.25  0
 b  -0.83  -0.2   0

每个百分比的公式是:

(counts of c(6,7) - counts of c(1,2,3,4)) / counts of c(1,2,3,4,5,6,7)。例如,要为X1a 获取-0.5

Where the columns is `X1` and `YY = a`, then:
prom = counts of c(6,7) = 1 
detr = counts of c(1,2,3,4) = 4 
total = counts of c(1,2,3,4,5,6,7) = 6 
The percentage is (prom - detr) / total = (1-4)/ 6 = -0.5

我正在尝试通过每列 (X1,X2, and X3) 上的循环来实现该输出,其中,对于每一列:

 > table(df[,X1], df$YY)
    a b
  1 0 1
  2 1 0
  3 1 2
  4 0 2
  5 1 1
  7 1 0

然后将ab 的相应计数相加。但我正在努力访问这个table(),并且对于每个YY,将各自的计数相加,休息它们,然后将它们除以计数的总数。我正在考虑使用expss::sum_if() 访问表格并按标准求和,但我仍然没有找到办法。

有没有更简单的方法呢?任何的想法?。我也尝试使用 dplyr,但是当我必须按类别分组并按列计数、求和和除以并以小输出结束时,它似乎更复杂。

【问题讨论】:

  • 1) 使用sample等函数时请使用set.seed()2) 请解释清楚。这个,(counts of c(6,7) - counts of c(1,2,3,4)) / counts of c(1,2,3,4,5,6,7) 我不清楚
  • 我开发了一个更好的例子。 set.seed() 是为了什么?
  • set.seed() 是为了确保重现性。 sample 函数每次运行时都会采样不同的值,除非你设置了种子
  • 一般来说,NPS 分数与mean(case_when(x %in% 1:4~ 1, x %in% 6:7 ~ -1, TRUE ~ 0)) 完全相同。如果您将原始比例重新编码为 -1、0、1,那么所有进一步的计算将变得更加简单。此外,您可以使用组间的 t 检验轻松进行显着性检验。

标签: r group-by dplyr


【解决方案1】:

YY 分组,然后使用指示的函数(以公式表示法表示)汇总每个分组的列。

library(dplyr)

df %>%
  group_by(YY) %>%
  summarize_all(~ (sum(.x %in% 6:7) - sum(.x %in% 1:4)) / sum(.x %in% 1:7)) %>%
  ungroup

给予:

# A tibble: 2 x 4
  YY       X1    X2    X3
  <fct> <dbl> <dbl> <dbl>
1 a     -0.5     -1     0
2 b      0.25    -1    -1

【讨论】:

  • 有效!谢谢 !你能解释一下summarize_all() 和ungroup() 是如何工作的吗?
  • (1) summarize(和summarize_all)用于使用指定的聚合函数将组中的所有行减少为单行。 (2) 将每个group_byungroup 匹配是一种很好的形式。在这种情况下,如果省略 ungroup,则会得到相同的结果,但在其他情况下,如果省略 ungroup,然后将输出馈送到新管道,则 group_by 的内存将被传递,这可能会给意想不到的结果。
【解决方案2】:

我们可以根据我们的公式创建一个函数get_ratio

get_ratio <- function(x) {
  (sum(x %in% 6:7) - sum(x %in% 1:4))/sum(x %in% 1:7)
}

现在将它应用于每个组 (YY)

library(dplyr)

df %>%
  group_by(YY) %>%
  summarise_at(vars(X1:X3), get_ratio)

#    YY       X1     X2    X3
#   <fct>    <dbl>  <dbl> <dbl>
#1    a     -0.5     -1     0
#2    b      0.25    -1    -1

【讨论】:

  • 它给了我这个错误: eval 中的错误(variables_names,envir = envir,enclos = baseenv()) :找不到对象'X1'。为什么会这样?
  • @Chris 不确定。你有不同名称的列而不是 X1, X2 吗?还要确保将上述命令应用于您原来的 df 而不是 table
  • 这是因为我使用的是 expss 的 vars。但是,这些值也不正确。 ://
  • 我看错了最后一部分。您想除以具有1:7 的值的数量。更新了功能,现在应该可以使用了。
【解决方案3】:

你想做这样的事吗?

    NPS_count <- function(x, prom=c(6,7), detr=seq(1:4)) {
      case_when(x %in% prom ~ 1,
                x %in% detr ~ -1,
                TRUE ~ 0)
    }


    df %>% 
  group_by(YY) %>% 
  summarise(X1 = sum(NPS_count(X1))/n(),
            X2 = sum(NPS_count(X2))/n(),
            X3 = sum(NPS_count(X3))/n())

【讨论】:

  • 你的输出结构是我要找的,但值不对:/
  • 我明白了,您想忽略 NPS 中的“5”
  • 只是为了舞会和detr。它必须包含在总数中:)
  • 同理,结构不错,但数值还是不对。我用 set.seed(100) 编辑了这个例子。上面显示的最终输出的值是正确的。
  • 这很奇怪。我对 set.seed(100) 的结果与您的问题 YY X1 X2 X3 1 a -0.25 -0.25 0 2 b -0.833 -0.167 0 相同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多