[英]Replace NA with group value in loop across multiple columns
我想用組值(不是平均值或中值,因為某些列是字符或因子)替換 NA,並且我想為所有使用相同組的列列表執行此操作。
樣本數據:
ID <- c(1,1,1,2,2,2,3,3)
V1 <- c(NA,"HEJ",NA,"BOS","BOS",NA,"IB","IB")
V2 <- c(700,700,NA,3000,NA,NA,NA,1000)
V3 <- c(NA,NA,3,1,1,1,2,NA)
V4 <- c(NA,NA,NA,NA,NA,"LA",NA,"FE")
mydf <- data.frame(ID,V1,V2,V3,V4)
> mydf
ID V1 V2 V3 V4
1 1 <NA> 700 NA <NA>
2 1 HEJ 700 NA <NA>
3 1 <NA> NA 3 <NA>
4 2 BOS 3000 1 <NA>
5 2 BOS NA 1 <NA>
6 2 <NA> NA 1 LA
7 3 IB NA 2 <NA>
8 3 IB 1000 NA FE
所以我知道如果我只想為一個專欄做這個,我會:
setDT(mydf)[, V1:=
V1[!is.na(V1)][1L],
by = ID]
然后得到:
> mydf
ID V1 V2 V3 V4
1: 1 HEJ 700 NA <NA>
2: 1 HEJ 700 NA <NA>
3: 1 HEJ NA 3 <NA>
4: 2 BOS 3000 1 <NA>
5: 2 BOS NA 1 <NA>
6: 2 BOS NA 1 LA
7: 3 IB NA 2 <NA>
8: 3 IB 1000 NA FE
但是我有很多列,所以我需要把它放在某種循環中。
期望的輸出:
> mydf
ID V1 V2 V3 V4
1: 1 HEJ 700 3 <NA>
2: 1 HEJ 700 3 <NA>
3: 1 HEJ 700 3 <NA>
4: 2 BOS 3000 1 LA
5: 2 BOS 3000 1 LA
6: 2 BOS 3000 1 LA
7: 3 IB 1000 2 FE
8: 3 IB 1000 2 FE
這就是我在沒有運氣的情況下嘗試過的:
names <- colnames(mydf[,-c(1)])
for(j in seq_along(nm1)){
set(mydf,
i = which(is.na(mydf[[names[j]]])),
j = names[j],
value = mydf[[names[j]]][is.na(mydf[[names[j]]])])
}
我也試過這個:
mydf[,-c(1] <- lapply(mydf, function(x)
replace(x, is.na(x), x[!is.na(x)]))
> mydf
ID V1 V2 V3 V4
1 1 1 HEJ 700 3
2 1 1 HEJ 700 1
3 1 1 BOS 700 3
4 2 2 BOS 3000 1
5 2 2 BOS 700 1
6 2 2 BOS 3000 1
7 3 3 IB 1000 2
8 3 3 IB 1000 1
如果我問的問題已經存在但我找不到,我很抱歉。 我希望有人能幫我清理我凌亂的數據:)
一個dplyr
和tidyr
possibilty 可能是:
mydf %>%
group_by(ID) %>%
fill(-ID, .direction = "downup")
ID V1 V2 V3 V4
<dbl> <fct> <dbl> <dbl> <fct>
1 1 HEJ 700 3 <NA>
2 1 HEJ 700 3 <NA>
3 1 HEJ 700 3 <NA>
4 2 BOS 3000 1 LA
5 2 BOS 3000 1 LA
6 2 BOS 3000 1 LA
7 3 IB 1000 2 FE
8 3 IB 1000 2 FE
我們可以使用.SDcols
將該函數應用於多列。
library(data.table)
cols <- names(mydf[-1])
setDT(mydf)
mydf[, (cols):= lapply(.SD, function(x)
replace(x, is.na(x), x[!is.na(x)][1])),.SDcols = cols, by = ID]
mydf
# ID V1 V2 V3 V4
#1: 1 HEJ 700 3 <NA>
#2: 1 HEJ 700 3 <NA>
#3: 1 HEJ 700 3 <NA>
#4: 2 BOS 3000 1 LA
#5: 2 BOS 3000 1 LA
#6: 2 BOS 3000 1 LA
#7: 3 IB 1000 2 FE
#8: 3 IB 1000 2 FE
我們可以使用zoo
na.locf
library(data.table)
setDT(df1)[, na.locf(.SD), by = ID, .SDcols = V2:V4]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.