![](/img/trans.png)
[英]R: Long-data: how to remove all following obs within same ID once condition is met?
[英]How can I conditionally remove data values the day after a condition is met within an R dataframe?
我正在處理的是一些環境數據,其中包括每日降雨總量。 我想刪除降雨總量超過零(雨> 0)的所有日子以及下雨事件后的所有日子的所有“值”(標記為“NA”)。 例如,如果在 2018 年 1 月 3 日下雨 >0,則將 'value' 列中的所有數據標記為 'NA' 對應於 1/3/2018 和 1/4/2018。對同一天做條件是很容易,但我也在摸索第二天如何參考。
這是一個示例 dataframe:
date <- seq(as.Date("2018-1-1"), as.Date("2018-1-5"), by =
"1 days")
plot <- rep(c(1:4), each = 5)
treatment <- rep(c('control','treat'),each = 10)
rain <- c(0,0,2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,2,0,0)
value <- (seq(1:20))
df <- data.frame(date, plot, treatment, rain,value)
df$date <- rep(date, length=nrow(df))
df
date plot treatment rain value
1 2018-01-01 1 control 0 1
2 2018-01-02 1 control 0 2
3 2018-01-03 1 control 2 3
4 2018-01-04 1 control 0 4
5 2018-01-05 1 control 0 5
6 2018-01-01 2 control 0 6
7 2018-01-02 2 control 0 7
8 2018-01-03 2 control 2 8
9 2018-01-04 2 control 0 9
10 2018-01-05 2 control 0 10
11 2018-01-01 3 treat 0 11
12 2018-01-02 3 treat 0 12
13 2018-01-03 3 treat 2 13
14 2018-01-04 3 treat 0 14
15 2018-01-05 3 treat 0 15
16 2018-01-01 4 treat 0 16
17 2018-01-02 4 treat 0 17
18 2018-01-03 4 treat 2 18
19 2018-01-04 4 treat 0 19
20 2018-01-05 4 treat 0 20
期望的結果:
date plot treatment rain value
1 2018-01-01 1 control 0 1
2 2018-01-02 1 control 0 2
3 2018-01-03 1 control 2 NA
4 2018-01-04 1 control 0 NA
5 2018-01-05 1 control 0 5
6 2018-01-01 2 control 0 6
7 2018-01-02 2 control 0 7
8 2018-01-03 2 control 2 NA
9 2018-01-04 2 control 0 NA
10 2018-01-05 2 control 0 10
11 2018-01-01 3 treat 0 11
12 2018-01-02 3 treat 0 12
13 2018-01-03 3 treat 2 NA
14 2018-01-04 3 treat 0 NA
15 2018-01-05 3 treat 0 15
16 2018-01-01 4 treat 0 16
17 2018-01-02 4 treat 0 17
18 2018-01-03 4 treat 2 NA
19 2018-01-04 4 treat 0 NA
20 2018-01-05 4 treat 0 20
(預先:所有這些解決方案都依賴於提前設置的排序。外部排序並不難,可能使用dplyr::arrange
或基本order
。)
使用dplyr
這可以通過以下方式完成:
library(dplyr)
df %>%
group_by(plot, treatment) %>%
mutate(value = if_else(rain > 0 | lag(rain > 0, default = FALSE), NA_integer_, value)) %>%
ungroup()
# # A tibble: 20 x 5
# date plot treatment rain value
# <chr> <int> <chr> <int> <int>
# 1 2018-01-01 1 control 0 1
# 2 2018-01-02 1 control 0 2
# 3 2018-01-03 1 control 2 NA
# 4 2018-01-04 1 control 0 NA
# 5 2018-01-05 1 control 0 5
# 6 2018-01-01 2 control 0 6
# 7 2018-01-02 2 control 0 7
# 8 2018-01-03 2 control 2 NA
# 9 2018-01-04 2 control 0 NA
# 10 2018-01-05 2 control 0 10
# 11 2018-01-01 3 treat 0 11
# 12 2018-01-02 3 treat 0 12
# 13 2018-01-03 3 treat 2 NA
# 14 2018-01-04 3 treat 0 NA
# 15 2018-01-05 3 treat 0 15
# 16 2018-01-01 4 treat 0 16
# 17 2018-01-02 4 treat 0 17
# 18 2018-01-03 4 treat 2 NA
# 19 2018-01-04 4 treat 0 NA
# 20 2018-01-05 4 treat 0 20
或者,使用data.table
library(data.table)
DT <- as.data.table(df)
DT[rain > 0 | shift(rain > 0), value := NA, by = .(plot, treatment)]
也許在 base-R 中不太優雅:
do.call(rbind.data.frame,
by(df, df[,c("plot", "treatment")], function(x) {
n <- nrow(x)
within(x, { value[ rain > 0 | c(FALSE, rain[-n] > 0) ] = NA })
})
)
(盡管最后一個可能不會保持行的順序相同)。
數據:
df <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
date plot treatment rain value
2018-01-01 1 control 0 1
2018-01-02 1 control 0 2
2018-01-03 1 control 2 3
2018-01-04 1 control 0 4
2018-01-05 1 control 0 5
2018-01-01 2 control 0 6
2018-01-02 2 control 0 7
2018-01-03 2 control 2 8
2018-01-04 2 control 0 9
2018-01-05 2 control 0 10
2018-01-01 3 treat 0 11
2018-01-02 3 treat 0 12
2018-01-03 3 treat 2 13
2018-01-04 3 treat 0 14
2018-01-05 3 treat 0 15
2018-01-01 4 treat 0 16
2018-01-02 4 treat 0 17
2018-01-03 4 treat 2 18
2018-01-04 4 treat 0 19
2018-01-05 4 treat 0 20")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.