簡體   English   中英

在跨多列的循環中用組值替換 NA

[英]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

如果我問的問題已經存在但我找不到,我很抱歉。 我希望有人能幫我清理我凌亂的數據:)

一個dplyrtidyr 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM