2016-11-08 50 views
2

假设我有数据集,它看起来像向前和向后携带最后一个因素观察组行中的R

ID Name 
1 JAY 
1 
1 JAY 
2 LAY 
2 LAY 
2 
3 NA 
3 KAY 
3 

我要填写基于这样的观察已经缺失值的行(空或NA)可在该组中使用。因此,得到的数据帧将看起来像

ID Name 
1 JAY 
1 JAY 
1 JAY 
2 LAY 
2 LAY 
2 LAY 
3 KAY 
3 KAY 
3 KAY 

我尝试使用na.locf,但它没有工作的非数值。

DF1 = setDT(DF)[, N := na.locf(na.locf(Name(NA_real_^!Name),na.rm=FALSE), fromLast=TRUE, na.rm=FALSE), ID][is.na(N), N := 0] 

回答

3

一个选项是“ID”分组后,子集“名称”不在NA,而不是一个空白(nzchar(Name)),得到最后的观察(tail(...))和分配(:=)到“名称”。

setDT(DF)[, Name := tail(Name[!is.na(Name) & nzchar(Name)], 1), by = ID] 
DF 
# ID Name 
#1: 1 JAY 
#2: 1 JAY 
#3: 1 JAY 
#4: 2 LAY 
#5: 2 LAY 
#6: 2 LAY 
#7: 3 KAY 
#8: 3 KAY 
#9: 3 KAY 

如果 '名称' 列factor变化nzchar(Name)nzchar(as.character(Name))


或指定的逻辑向量 '我' 和分配(:=)的最后一次观察(Name[.N])为'名称'分组后'

setDT(DF)[!is.na(Name) & nzchar(Name), Name := Name[.N], ID] 

注意:对于第二个解决方案的工作,'名称'应是character班。

2

基准R中的解决方案(使用splitdo.call(bind, ...)。假设d包含您dataframe:文本载体

tmp <- lapply(split(d, d$ID), function(x) { 
    # Explanation: 
    # decreasing = TRUE so that empty strings are at the end 
    # na.last = NA so that NA's are omitted 
    x$Name <- sort(x$Name, decreasing = TRUE, na.last = NA)[1]; 
    return(x); 
}) 

d.new <- do.call(rbind, tmp); 

print(d.new); 
ID Name 
1.1 1 JAY 
1.2 1 JAY 
1.3 1 JAY 
2.4 2 LAY 
2.5 2 LAY 
2.6 2 LAY 
3.7 3 KAY 
3.8 3 KAY 
3.9 3 KAY 
0

na.locf的作品,我觉得你的data.table语法可能与它搞乱。我没有使用过那么多的软件包,所以不能说明如何。

这工作得很好:

df <- data.frame('ID' = c(1,1,1,2,2,2,3,3,3), 
       'Name' = c('JAY', '', 'JAY', 'LAY', 'LAY', '', NA, 'KAY', ''), 
       stringsAsFactors = FALSE) 

df$Name <- na.locf(df$Name, fromLast = TRUE) # takes care of 'KAY'  

df[df==''] <- NA 

df$Name <- na.locf(df$Name) # takes care of the rest 

已经发布的基础R解决方案也非常好,通过ID拆分为您提供了替代品是如何发生的更多的控制。我之前用()做过类似的事情。