从na.locf()向填充的NA添加增量字母

时间:2019-02-21 16:23:52

标签: r increment na

我有一个data.frame,看起来像这样:

df <- structure(list(
  a = c("atg", "tga", "agt", "acc", "cgt", "gca",
    "gtc", "ggg", "ccc"),
  b = c("1", "2", NA, "3", NA, NA, "4", "5",
    "6")
),
row.names = c(NA, -9L),
class = "data.frame")

我已使用NAs包中的non-NA用最接近的na.locf替换了zoo,但是我需要向替换的{{1} }值,以便最终产品看起来像这样:

NA

我写了一个小的> df a b 1 atg 1 2 tga 2 3 agt 2a 4 acc 3 5 cgt 3a 6 gca 3b 7 gtc 4 8 ggg 5 9 ccc 6 函数,该函数适当地填充了if,但在所有值中添加了字母,并回收了数字以匹配NA的长度。我可以看到,这个结果来自我现在想使用的函数中的letters调用,我可能需要做一个any循环,并使用它来遍历每个单元格,但是forfor语句的变体循环不会执行任何操作。欢迎任何建议。

if

3 个答案:

答案 0 :(得分:3)

定义seq_let,如果参数为全NA,则给出字母序列,其参数为长度,否则为“”。然后使用averleid对NA和非NA运行进行分组,并将seq_let应用于每个以na.locf0(b)为前缀的组。

library(data.table)
library(zoo)

seq_let <- function(x) if (all(is.na(x))) letters[seq_along(x)] else ""
transform(df, b = paste0(na.locf0(b), ave(b, rleid(is.na(b)), FUN = seq_let)))

给予:

    a  b
1 atg  1
2 tga  2
3 agt 2a
4 acc  3
5 cgt 3a
6 gca 3b
7 gtc  4
8 ggg  5
9 ccc  6

答案 1 :(得分:2)

使用zoo和基础R

x=zoo::na.locf(df$b)
s=as.numeric(ave(x,x,FUN=function(x) seq_along(x)))-1
x[s!=0]=paste0(x[s!=0],letters[s])
df$b=x
df
    a  b
1 atg  1
2 tga  2
3 agt 2a
4 acc  3
5 cgt 3a
6 gca 3b
7 gtc  4
8 ggg  5
9 ccc  6

答案 2 :(得分:0)

Create counter within consecutive runs of certain values借用代码:

i <- is.na(df$b)
g <- cumsum(i)
df$b <- paste0(na.locf(df$b), c("", letters)[g - cummax((!i) * g) + 1])

#     a  b
# 1 atg  1
# 2 tga  2
# 3 agt 2a
# 4 acc  3
# 5 cgt 3a
# 6 gca 3b
# 7 gtc  4
# 8 ggg  5
# 9 ccc  6

使用data.table更紧凑,从Count consecutive TRUE values within each block separately

中提取主要思想
library(data.table)

setDT(df)[ ,  b := paste0(na.locf(b), c("", letters)[rowid(rleid(b)) * is.na(b) + 1])]

#      a  b
# 1: atg  1
# 2: tga  2
# 3: agt 2a
# 4: acc  3
# 5: cgt 3a
# 6: gca 3b
# 7: gtc  4
# 8: ggg  5
# 9: ccc  6