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。您计算 am
和 check
在 count()
中存在多少个数据点。然后,您使用 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
如果这是重复,我深表歉意,我真的不知道我想要实现的目标的正确术语。
我有一个药物实验室结果的数据框,如下所示:
╔══════╦════════╗ ║ 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。您计算 am
和 check
在 count()
中存在多少个数据点。然后,您使用 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