以下是示例:数据和错误解决方案:
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解决方案。感谢。
答案 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))