仅替换另一列中的最后一个NA给定ID

时间:2016-01-11 12:36:00

标签: r

以下是示例:数据和错误解决方案:

df <- data.frame(id=c(1,1,2,2,2,3,4,5,5), val=c(NA,1.5,1,NA,NA,5,NA,2,NA), rep=1:9)

将另一列中的NA替换为id。这是我尝试过的(其中包括):

funrep <- function(x) { is.na(tail(x, 1)) } 
df$val[as.logical(with(df, ave(val, id, FUN=funrep)))] <- df$rep[as.logical(with(df, ave(val, id, FUN=funrep)))]

以上内容替换了id来自另一列没有NA的数字。

期望的输出:

 id val rep val2
  1  NA   1   NA 
  1 1.5   2  1.5
  2 1.0   3  1.0
  2  NA   4  NA
  2  NA   5  5 
  3 5.0   6  5.0
  4  NA   7  7
  5 2.0   8  2.0
  5  NA   9  9

编辑:列val2中的值已更正。我也更喜欢基地R解决方案。感谢。

1 个答案:

答案 0 :(得分:1)

使用data.table,我们会转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df),创建&#34; val2&#34;列&#34; val&#34;,根据&#34; ID&分组的逻辑条件获取行索引(.I) #34;,提取该列($V1)。在&#34; i&#34;中使用该索引,我们将&#34; val2&#34;分配给&#34; rep&#中的相应元素34。

library(data.table)
i1 <- setDT(df)[, val2:= val][, .I[1:.N==.N & is.na(val)] , id]$V1
df[i1, val2:= as.numeric(rep)]
df
#     id val rep val2
#1:  1  NA   1   NA
#2:  1 1.5   2  1.5
#3:  2 1.0   3  1.0
#4:  2  NA   4   NA
#5:  2  NA   5  5.0
#6:  3 5.0   6  5.0
#7:  4  NA   7  7.0
#8:  5 2.0   8  2.0
#9:  5  NA   9  9.0

使用base R,我们使用transform创建一个新列,split将数据框列为split,使用ifelse更改值in&#39; val2&#39;与&#39; rep&#39;满足条件,unsplit得到预期的输出。

 unsplit(lapply(split(transform(df, val2=val), df$id), 
     function(x) transform(x, val2=ifelse(is.na(val2) & 
       1:nrow(x)==nrow(x), rep, val2))), df$id)

或使用ave

 i2 <- with(df, ave(is.na(val), id, FUN=function(x) x &
               seq_along(x)==length(x)))
 with(df, ifelse(i2, rep, val))