如何在R中按组省略两个最高值和最低值的行
How to omit rows of two highest and the lowest value by group in R
这似乎是一个非常基本的问题,但我似乎找不到解决方案。
如何通过 R 中的几个因素删除 variable
的两个最高值和 最低值的(三)行?我稍微修改了 airquality
以获得示例(抱歉,我还是个初学者):
set.seed(1)
airquality$var1 <- c(sample(1:3, 153, replace=T))
airquality$var2 <- c(sample(1:2, 153, replace=T))
airquality2 <- airquality
airquality2$Solar.R <- as.numeric(airquality2$Solar.R)
airquality2$Solar.R <- airquality2$Solar.R*2
airquality3 <- airquality
airquality3$Solar.R <- as.numeric(airquality3$Solar.R)
airquality3$Solar.R <- airquality3$Solar.R*2.5
test <- round(na.omit(rbind(airquality, airquality2, airquality3)))
test$var1 <- factor(test$var1)
test$var2 <- factor(test$var2)
head(test)
得出:
head(test)
# Ozone Solar.R Wind Temp Month Day var1 var2
# 1 41 190 7 67 5 1 1 1
# 2 36 118 8 72 5 2 2 2
# 3 12 149 13 74 5 3 2 1
# 4 18 313 12 62 5 4 3 2
# 7 23 299 9 65 5 7 3 1
# 8 19 99 14 59 5 8 2 1
现在我想用 group_by(Month, var1, var2)
之类的东西删除具有 Solar.R
的两个最高值和最低值的行。由于有 30 个因子组合 (5*3*2),因此应省略 90 行。其余数据应保持不变。我查看了 Min
& Max
,但无法正常工作。任何帮助将不胜感激。
我想你在找 slice
:
library("dplyr")
sliced =
test %>%
group_by(Month, var1, var2) %>% # group
arrange(Solar.R) %>% # within-group, order by Solar.R
slice(3:(n() - 2)) # keep the 3rd through the 3rd-to-last row
nrow(sliced)
# [1] 233
编辑:我一开始有3:(n() - 3)
,更正为3:(n() - 2)
。一个很好的健全性检查是考虑 (1:10)[3:(10 - 3)]
与 (1:10)[3:(10 - 2)]
。我没有费心阅读您的模拟代码,但是当我用 n_group()
检查时,我看到了 27 个组,而不是您问题中所述的 30 个。 (也许是种子问题,rawr 的 set.seed(1)
有 28 个组。)
更多编辑: 根据您的编辑,您可能想要省略最低值和两个最高值,而不是两个最低值和两个最高值。只需将 3:(n() - 2))
更改为 2:(n() - 2)
即可进行调整。
这里有一个 data.table 的方法,但我想 dplyr 会更冗长。
require(data.table)
set.seed(1)
airquality$var1 <- c(sample(1:3, 153, replace=T))
airquality$var2 <- c(sample(1:2, 153, replace=T))
airquality2 <- airquality
airquality2$Solar.R <- as.numeric(airquality2$Solar.R)
airquality2$Solar.R <- airquality2$Solar.R*2
airquality3 <- airquality
airquality3$Solar.R <- as.numeric(airquality3$Solar.R)
airquality3$Solar.R <- airquality3$Solar.R*2.5
test <- round(na.omit(rbind(airquality, airquality2, airquality3)))
test$var1 <- factor(test$var1)
test$var2 <- factor(test$var2)
dt_test <- as.data.table(test)
dt_test[,.SD[order(-Solar.R)][c(3:(.N-1))],.(Month,var1,var2)]
我们也可以使用 .I
来获取 data.table
中的行索引,然后以此为基础对其进行子集化。
library(data.table)
i1 <- setDT(test)[order(Solar.R), .I[3:(.N-1)],.(Month, var1, var2)]$V1
test[i1]
这似乎是一个非常基本的问题,但我似乎找不到解决方案。
如何通过 R 中的几个因素删除 variable
的两个最高值和 最低值的(三)行?我稍微修改了 airquality
以获得示例(抱歉,我还是个初学者):
set.seed(1)
airquality$var1 <- c(sample(1:3, 153, replace=T))
airquality$var2 <- c(sample(1:2, 153, replace=T))
airquality2 <- airquality
airquality2$Solar.R <- as.numeric(airquality2$Solar.R)
airquality2$Solar.R <- airquality2$Solar.R*2
airquality3 <- airquality
airquality3$Solar.R <- as.numeric(airquality3$Solar.R)
airquality3$Solar.R <- airquality3$Solar.R*2.5
test <- round(na.omit(rbind(airquality, airquality2, airquality3)))
test$var1 <- factor(test$var1)
test$var2 <- factor(test$var2)
head(test)
得出:
head(test)
# Ozone Solar.R Wind Temp Month Day var1 var2
# 1 41 190 7 67 5 1 1 1
# 2 36 118 8 72 5 2 2 2
# 3 12 149 13 74 5 3 2 1
# 4 18 313 12 62 5 4 3 2
# 7 23 299 9 65 5 7 3 1
# 8 19 99 14 59 5 8 2 1
现在我想用 group_by(Month, var1, var2)
之类的东西删除具有 Solar.R
的两个最高值和最低值的行。由于有 30 个因子组合 (5*3*2),因此应省略 90 行。其余数据应保持不变。我查看了 Min
& Max
,但无法正常工作。任何帮助将不胜感激。
我想你在找 slice
:
library("dplyr")
sliced =
test %>%
group_by(Month, var1, var2) %>% # group
arrange(Solar.R) %>% # within-group, order by Solar.R
slice(3:(n() - 2)) # keep the 3rd through the 3rd-to-last row
nrow(sliced)
# [1] 233
编辑:我一开始有3:(n() - 3)
,更正为3:(n() - 2)
。一个很好的健全性检查是考虑 (1:10)[3:(10 - 3)]
与 (1:10)[3:(10 - 2)]
。我没有费心阅读您的模拟代码,但是当我用 n_group()
检查时,我看到了 27 个组,而不是您问题中所述的 30 个。 (也许是种子问题,rawr 的 set.seed(1)
有 28 个组。)
更多编辑: 根据您的编辑,您可能想要省略最低值和两个最高值,而不是两个最低值和两个最高值。只需将 3:(n() - 2))
更改为 2:(n() - 2)
即可进行调整。
这里有一个 data.table 的方法,但我想 dplyr 会更冗长。
require(data.table)
set.seed(1)
airquality$var1 <- c(sample(1:3, 153, replace=T))
airquality$var2 <- c(sample(1:2, 153, replace=T))
airquality2 <- airquality
airquality2$Solar.R <- as.numeric(airquality2$Solar.R)
airquality2$Solar.R <- airquality2$Solar.R*2
airquality3 <- airquality
airquality3$Solar.R <- as.numeric(airquality3$Solar.R)
airquality3$Solar.R <- airquality3$Solar.R*2.5
test <- round(na.omit(rbind(airquality, airquality2, airquality3)))
test$var1 <- factor(test$var1)
test$var2 <- factor(test$var2)
dt_test <- as.data.table(test)
dt_test[,.SD[order(-Solar.R)][c(3:(.N-1))],.(Month,var1,var2)]
我们也可以使用 .I
来获取 data.table
中的行索引,然后以此为基础对其进行子集化。
library(data.table)
i1 <- setDT(test)[order(Solar.R), .I[3:(.N-1)],.(Month, var1, var2)]$V1
test[i1]