从按变量分组的数据框中搜索并删除异常值
Search for and remove outliers from a dataframe grouped by a variable
我有一个包含 5 个变量和 800 行的数据框:
head(df)
V1 variable value element OtolithNum
1 24.9835 V7 130230.0 Mg 25
2 24.9835 V8 145844.0 Mg 25
3 24.9835 V9 126126.0 Mg 25
4 24.9835 V10 103152.0 Mg 25
5 24.9835 V11 129571.9 Mg 25
6 24.9835 V12 114214.0 Mg 25
我需要执行以下操作:
- 确定所有值(来自 "value" 变量)与中位数的 > 2 个标准差,按元素变量分组。
- 从数据框中删除离群值(或创建一个排除离群值的新数据框。
我一直在使用 dplyr 包并使用以下代码按 "element" 变量分组,并提供平均值:
df1=df %>%
group_by(element) %>%
summarise_each(funs(mean), value)
你能帮我操作或添加到上面的代码中,以便在我提取均值之前删除由 "element" 变量分组的异常值(上面定义,从中位数算起 >2 sd)。
我尝试了另一个帖子中的以下代码(这就是为什么数据名称与我上面的个人数据不匹配),但没有成功:
#standardize each column (we use it in the outdet function)
scale(dat)
#create function that looks for values > +/- 2 sd from mean
outdet <- function(x) abs(scale(x)) >= 2
#index with the function to remove those values
dat[!apply(sapply(dat, outdet), 1, any), ]
这是一个使用 base R 的方法:
element <- sample(letters[1:5], 1e4, replace=T)
value <- rnorm(1e4)
df <- data.frame(element, value)
means.without.ols <- tapply(value, element, function(x) {
mean(x[!(abs(x - median(x)) > 2*sd(x))])
})
并使用 dplyr
df1 = df %>%
group_by(element) %>%
filter(!(abs(value - median(value)) > 2*sd(value))) %>%
summarise_each(funs(mean), value)
结果比较:
> means.without.ols
a b c d e
-0.008059215 -0.035448381 -0.013836321 -0.013537466 0.021170663
> df1
Source: local data frame [5 x 2]
element value
1 a -0.008059215
2 b -0.035448381
3 c -0.013836321
4 d -0.013537466
5 e 0.021170663
我有一个包含 5 个变量和 800 行的数据框:
head(df)
V1 variable value element OtolithNum
1 24.9835 V7 130230.0 Mg 25
2 24.9835 V8 145844.0 Mg 25
3 24.9835 V9 126126.0 Mg 25
4 24.9835 V10 103152.0 Mg 25
5 24.9835 V11 129571.9 Mg 25
6 24.9835 V12 114214.0 Mg 25
我需要执行以下操作:
- 确定所有值(来自 "value" 变量)与中位数的 > 2 个标准差,按元素变量分组。
- 从数据框中删除离群值(或创建一个排除离群值的新数据框。
我一直在使用 dplyr 包并使用以下代码按 "element" 变量分组,并提供平均值:
df1=df %>%
group_by(element) %>%
summarise_each(funs(mean), value)
你能帮我操作或添加到上面的代码中,以便在我提取均值之前删除由 "element" 变量分组的异常值(上面定义,从中位数算起 >2 sd)。
我尝试了另一个帖子中的以下代码(这就是为什么数据名称与我上面的个人数据不匹配),但没有成功:
#standardize each column (we use it in the outdet function)
scale(dat)
#create function that looks for values > +/- 2 sd from mean
outdet <- function(x) abs(scale(x)) >= 2
#index with the function to remove those values
dat[!apply(sapply(dat, outdet), 1, any), ]
这是一个使用 base R 的方法:
element <- sample(letters[1:5], 1e4, replace=T)
value <- rnorm(1e4)
df <- data.frame(element, value)
means.without.ols <- tapply(value, element, function(x) {
mean(x[!(abs(x - median(x)) > 2*sd(x))])
})
并使用 dplyr
df1 = df %>%
group_by(element) %>%
filter(!(abs(value - median(value)) > 2*sd(value))) %>%
summarise_each(funs(mean), value)
结果比较:
> means.without.ols
a b c d e
-0.008059215 -0.035448381 -0.013836321 -0.013537466 0.021170663
> df1
Source: local data frame [5 x 2]
element value
1 a -0.008059215
2 b -0.035448381
3 c -0.013836321
4 d -0.013537466
5 e 0.021170663