我想根據 ID 組中的一段時間填充 data.frame 的缺失值。
對于同一ID組中的最新registration_dat,我想填寫ID組中以前的值,但前提是registration_dat在ID組中最新registration_dat的1年內。
我的資料的示例版本:
ID registration_dat value1 value2
1 2020-03-04 NA NA
1 2019-05-06 33 25
1 2019-01-02 32 21
3 2021-10-31 NA NA
3 2018-10-12 33 NA
3 2018-10-10 25 35
4 2020-01-02 NA NA
4 2019-10-31 32 83
4 2019-09-20 33 56
8 2019-12-12 NA NA
8 2019-10-31 NA 43
8 2019-08-12 32 46
期望的輸出:
ID registration_dat value1 value2
1 2020-03-04 33 25
1 2019-05-06 33 25
1 2019-01-02 32 21
3 2021-10-31 NA NA
3 2018-10-12 33 NA
3 2018-10-10 25 35
4 2020-01-02 32 83
4 2019-10-31 32 83
4 2019-09-20 33 56
8 2019-12-12 32 43
8 2019-10-31 NA 43
8 2019-08-12 32 46
我稍后會過濾資料,以便我根據最新的注冊日期獲得一個唯一 ID,并且我希望這一行丟失的資料盡可能少,因此我想對資料框中的所有列執行此操作。但是,如果 NA 值與最新注冊日期相差超過 1 年,我不希望 NA 值被之前日期的值填充。我的資料框有 14 列和 300 萬多行,所以我需要它來處理比示例中顯示的更大的 data.frame。
我會很感激任何想法!
uj5u.com熱心網友回復:
您可以使用across()同時操作多個列。請注意,我使用date1 - years(1) <= date2而不是date1 - 365 <= date2確定日期是否在最新日期的 1 年內,這可以考慮閏年(366 天)。
library(dplyr)
library(lubridate)
df %>%
group_by(ID) %>%
arrange(desc(registration_dat), .by_group = TRUE) %>%
mutate(across(starts_with("value"),
~ if_else(row_number() == 1 & is.na(.x) & registration_dat - years(1) <= registration_dat[which.max(!is.na(.x))],
.x[which.max(!is.na(.x))], .x))) %>%
ungroup()
# # A tibble: 12 x 4
# ID registration_dat value1 value2
# <int> <date> <int> <int>
# 1 1 2020-03-04 33 25
# 2 1 2019-05-06 33 25
# 3 1 2019-01-02 32 21
# 4 3 2021-10-31 NA NA
# 5 3 2018-10-12 33 NA
# 6 3 2018-10-10 25 35
# 7 4 2020-01-02 32 83
# 8 4 2019-10-31 32 83
# 9 4 2019-09-20 33 56
# 10 8 2019-12-12 32 43
# 11 8 2019-10-31 NA 43
# 12 8 2019-08-12 32 46
資料
df <- structure(list(ID = c(1L, 1L, 1L, 3L, 3L, 3L, 4L, 4L, 4L, 8L,
8L, 8L), registration_dat = structure(c(18325, 18022, 17898,
18931, 17816, 17814, 18263, 18200, 18159, 18242, 18200, 18120
), class = "Date"), value1 = c(NA, 33L, 32L, NA, 33L, 25L, NA,
32L, 33L, NA, NA, 32L), value2 = c(NA, 25L, 21L, NA, NA, 35L,
NA, 83L, 56L, NA, 43L, 46L)), class = "data.frame", row.names = c(NA,-12L))
uj5u.com熱心網友回復:
您可以創建一個小函式(f下面的)來處理每個值列。
- 制作一個分組ID,并生成一個
rowid(這只是為了保留您的原始訂單)
dat <- dat %>%
mutate(rowid = row_number()) %>%
arrange(registration_dat) %>%
group_by(ID)
- 制作一個函式,它接受一個
df和val列,并回傳并更新df為val固定
f <- function(df, val) {
bind_rows(
df %>% filter(is.na({{val}}) & row_number()!=n()),
df %>% filter(!is.na({{val}}) | row_number()==n()) %>%
mutate({{val}} := if_else(is.na({{val}}) & registration_dat-lag(registration_dat)<365, lag({{val}}),{{val}}))
)
}
- 將函式應用于感興趣的列
dat = f(dat,value1)
dat = f(dat,value2)
- 如果需要,請恢復原始訂單
dat %>% arrange(rowid) %>% select(-rowid)
輸出:
ID registration_dat value1 value2
<int> <date> <int> <int>
1 1 2020-03-04 33 25
2 1 2019-05-06 33 25
3 1 2019-01-02 32 21
4 3 2021-10-31 NA NA
5 3 2018-10-12 33 NA
6 3 2018-10-10 25 35
7 4 2020-01-02 32 83
8 4 2019-10-31 32 83
9 4 2019-09-20 33 56
10 8 2019-12-12 32 46
11 8 2019-10-31 NA 43
12 8 2019-08-12 32 46
更新:
OP 想要每個 ID 的最后一行(即最后一個 registration_dat)。有 300 萬行和 14 個值列,我會使用data.table并執行以下操作:
library(data.table)
f <- function(df) {
df = df[df[1,registration_dat]-registration_dat<=365]
df[1,value:=df[2:.N][!is.na(value)][1,value]][1]
}
dcast(
melt(setDT(dat), id=c("ID", "registration_dat"))[order(-registration_dat),f(.SD), by=.(ID,variable)],
ID registration_dat~variable, value.var="value"
)
輸出:
ID registration_dat value1 value2
<int> <Date> <int> <int>
1: 1 2020-03-04 33 25
2: 3 2021-10-31 NA NA
3: 4 2020-01-02 32 83
4: 8 2019-12-12 32 43
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/459009.html
上一篇:GoogleAppScripts-獲得一個不變的“昨天”
下一篇:如何使用GetElementsByTagName/SelectNode/SelectSingleNode為XML檢索特定標簽內的標簽?
