我有一个包含 1000 行的 df。简化后看起来像这样:
df1 <- data.frame(Sample = c('A1', 'B2', 'C3', 'A1', 'B2', 'C3','A1', 'B2', 'C3'),
Day = c('1', '3', '5', '4', '2', '6','5', '4', '2' ),
Value = c('0.1', '0.8', '0.7', '0.6', '0.3', '0.4', '0.4', '0.2', '0.3'))
我想删除在测量最大值后几天出现的样本。
我可以查看每个样本的最大值以及它们落在哪几天:
library(dplyr)
df2 <- df1 %>%
group_by(Value, Day, Sample) %>%
slice(which.max(Value))
然后,如果我可以删除在测量最大值后几天发生的每个样本的行,我将获得所需的 df:
df3 <- data.frame(Sample = c('A1', 'B2', 'C3', 'A1', 'B2', 'C3'),
Day = c('1', '3', '5', '4', '2','2' ),
Value = c('0.1', '0.8', '0.7', '0.6', '0.3', '0.3'))
这似乎需要一个 for 循环,但我今天没有在很多气缸上开火,所以非常感谢任何帮助。 TIA。
答案 0 :(得分:1)
示例数据创建时使用数字列作为 character
(注意 '0.1'
而不是 0.1
),因此我们使用 type.convert
自动转换列类型, arrange
按'Sample'、'Day' 的数据,然后按'Sample' 分组,得到'Value' 最大值的索引,加1 并删除(-
) 带有{{ 的行1}}
slice
-输出
library(dplyr)
df1 %>%
type.convert(as.is = TRUE) %>%
arrange(Sample, Day) %>%
group_by(Sample) %>%
slice(-(which.max(Value) + 1)) %>%
ungroup
如果我们想去掉 # A tibble: 6 x 3
Sample Day Value
<chr> <int> <dbl>
1 A1 1 0.1
2 A1 4 0.6
3 B2 2 0.3
4 B2 3 0.8
5 C3 2 0.3
6 C3 5 0.7
之后的所有行(在 max
ing by 'Day', 'Sample' 之后)
arrange
或者将 df1 %>%
type.convert(as.is = TRUE) %>%
arrange(Sample, Day) %>%
group_by(Sample) %>%
filter(cumsum(cumsum(Value == max(Value, na.rm = TRUE))) <= 1) %>%
ungroup
与 slice
一起使用
seq
答案 1 :(得分:0)
使用 ave
-
df1 <- type.convert(df1, as.is = TRUE)
df1 <- df1[with(df1, order(Sample, Day)), ]
subset(df1, as.logical(ave(Value, Sample,
FUN = function(x) seq_along(x) <= match(max(x), x))))
# Sample Day Value
#1 A1 1 0.1
#4 A1 4 0.6
#5 B2 2 0.3
#2 B2 3 0.8
#9 C3 2 0.3
#3 C3 5 0.7