R 按组对数据帧进行汇总统计

R summary statistics from dataframe by group

如果这是重复,我深表歉意,我真的不知道我想要实现的目标的正确术语。

我有一个药物实验室结果的数据框,如下所示:

╔══════╦════════╗
║ drug ║ result ║
╠══════╬════════╣
║ A    ║     10 ║
║ B    ║    150 ║
║ B    ║     50 ║
║ A    ║     14 ║
║ C    ║      3 ║
║ C    ║      7 ║
╚══════╩════════╝

对于每种药物,我使用 dplyr 使用以下方法删除异常值(> 4 SD's from the mean):

cleaned <- data %>% group_by(drug) %>% filter(abs(result-mean(result))/sd(result) < 4)

但现在我想知道每种药物要去除多少异常值,所以基本上我想生成如下所示的数据框:

╔══════╦═══════════╦══════════╦════════════╗
║ drug ║ total (N) ║ outliers ║ % outliers ║
╠══════╬═══════════╬══════════╬════════════╣
║ A    ║       100 ║        7 ║ 0.07       ║
║ B    ║       200 ║       45 ║ 0.225      ║
║ C    ║       300 ║       99 ║ 0.33       ║
╚══════╩═══════════╩══════════╩════════════╝

执行此操作的最佳方法是什么?

我不会直接使用 filter(),而是创建一个标志字段(即 1 或 0)来指示结果是否为异常值,然后将其通过管道传输到适当的摘要中。

由于没有样本数据,所以决定使用mtcars数据集进行演示。如果我按照你的方法,下面将是一种方法。在这里,你想找出你过滤掉的那部分数据;您使用 setdiff() 来收集数据。由于 am 是本演示中的组变量,因此使用 count() 并找出每个组存在多少离群值(即,am 为 0 或 1)。您进一步尝试使用 select 和 unlist 获取所需的向量。然后,您使用 summarise() 并计算 am 存在多少数据点,并使用 mutate().

添加新列
library(dplyr)
library(tidyr)

mtcars %>%
group_by(am) %>%
filter(abs(disp-mean(disp))/sd(disp) < 1) %>%
setdiff(mtcars, .) %>%
count(am) %>%
select(2) %>%
unlist-> out

#out
#n1 n2 
#8  2 

summarize(group_by(mtcars, am), total = n()) %>%
mutate(outliers = out, percent = outliers / total)

#     am total outliers   percent
#  (dbl) (int)    (int)     (dbl)
#1     0    19        8 0.4210526
#2     1    13        2 0.1538462

听取了 devmacrile 的建议,我做了以下事情。首先,您使用组变量对数据进行分组。然后,您要设置一个标志列。在这里,我创建了带有 mutate() 的列。您在列中有 TRUE 和 FALSE。您计算 amcheckcount() 中存在多少个数据点。然后,您使用 tidyr 包中的 spread() 重塑结果。现在您计算 am 中第 0 组和第 1 组的总数据点。再次将数据分组 am,最后在 transmute() 中处理百分比计算和列重命名。希望这个示例对您有所帮助。

mtcars %>%
group_by(am) %>%
mutate(check = abs(disp-mean(disp))/sd(disp) < 1)  %>%
count(am, check) %>%
spread(check, n) %>%
mutate(total = `FALSE` + `TRUE`) %>%
group_by(am) %>%
transmute(total, outliers = `FALSE`, percentage = `FALSE` / total)

#     am total outliers percentage
#  (dbl) (int)    (int)      (dbl)
#1     0    19        8  0.4210526
#2     1    13        2  0.1538462