按组从数据框中获取R摘要统计信息

3

如果这是重复的,请原谅,我真的不知道我想要实现的正确术语。

我有一个药品实验室结果的数据框如下:

╔══════╦════════╗
║ 药品 ║ 结果   ║
╠══════╬════════╣
║ A    ║     10 ║
║ B    ║    150 ║
║ B    ║     50 ║
║ A    ║     14 ║
║ C    ║      3 ║
║ C    ║      7 ║
╚══════╩════════╝

对于每种药品,我正在使用dplyr来去除离群值(大于平均值4个标准差):

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

现在我想知道每种药物移除了多少异常值,因此我想生成一个类似以下的数据框:
╔══════╦═══════════╦══════════╦════════════╗
║ 药物  ║ 总数 (N) ║ 异常值   ║ % 异常值   ║
╠══════╬═══════════╬══════════╬════════════╣
║ A    ║       100 ║        7 ║ 0.07       ║
║ B    ║       200 ║       45 ║ 0.225      ║
║ C    ║       300 ║       99 ║ 0.33       ║
╚══════╩═══════════╩══════════╩════════════╝
最好的方法是什么?
2个回答

4

由于没有示例数据,我决定使用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两种取值。您可以使用count()函数计算amcheck中存在的数据点数。接下来,您可以使用tidyr包中的spread()函数重塑结果。现在,您可以计算0组和1组中am的总数据点数。再次使用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

2

不要直接使用filter()方法,我建议创建一个标识字段(即1或0),表示结果是否为异常值,然后将其传递到相应的汇总函数中。


2
我刚学会如何使用 summarize。我只使用了约一周的 R,如果有更好的方法,请告诉我:isnorm <- function(x) { sum(abs(x-mean(x))/sd(x) < 4) }summarize(data %>% group_by(drug), N=n(), normal=isnorm(test), outliers=N-normal, out_pct=outliers/N) - Alexander David
1
@AlexanderDavid 是的,看起来没问题。更符合惯用语的方式是将整个过程链接在一起,就像 data %>% group_by(drug) %>% summarise(...) 这样。 - Frank

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