有条件地填充 R 中的缺失数据

Conditionally filling missing data in R

我有一个数据框:

df$v1 = c('2', '', '', '', '3', '', '4', '', '', 'OT')

我想将此变量格式化为序数变量。然而,

df$v1 = as.ordered(df$v1)

结果:

Ord.factor w/ 5 levels ""<"2"<"3"<"4"<..: 2 1 1 1 3 1 4 1 1 5

R 将空单元格读取为唯一条目,并将它们放在首位进行排序。我想做的是用它上方(或左侧取决于您的方向)的最后一个单元格的值填充空单元格以获得值。换句话说,这个向量实际上应该是这样的:

df$v1 = c('2', '2', '2', '2', '3', '3', '4', '4', '4', 'OT')

我相信此更改将使我能够根据需要将变量格式化为序数。我已经尝试了 as.ordered(), as.factor(), levels = c('1', '2', '3', '4', 'OT'),并订购 = TRUE。但是,R 在包含时不使用 "levels" 或 "ordered" 参数; as.factor() 函数在不使用 "levels" 或 "ordered" 参数的情况下不会产生序数变量;并且,as.ordered() 函数解决了上述问题。因此,我认为在转换前填充空单元格是最好的解决方案。最好的方法是什么?我知道我可以使用:

df$v1 = as.ordered(sub('^$', '2', df$v1))

用“2”填充空单元格;但是,每个单元格的重置值不同。我可以这样做:

df.a = df[1:4, ]
df.b = df[5:6, ]
df.c = df[7:9, ]
df.d = df[10, ]
df.a$v1 = as.ordered(sub('^$', '2', df.a$v1))
df.b$v1 = as.ordered(sub('^$', '3', df.b$v1))
df.c$v1 = as.ordered(sub('^$', '4', df.c$v1))

但是,我正在寻找一种自动执行此操作的方法。虽然上面的 7 行会产生我在这种情况下想要的结果,但我还有许多其他表格也遇到了同样的格式问题;并且,对应于每个必要分区的行数对于每个分区都是不同的。非常感谢您的帮助。

tidyr 包中的 fill 怎么样?

library(tidyr)

df$v1 <- ifelse(df$v1 == '', NA, df$v1) # requires NA not empty string
df <- df %>% fill(v1)

我们可以使用 zoo 中的 na.locf 将空白 ("") 转换为 NA

后,将 NA 元素替换为非 NA 先前相邻元素
library(zoo)
df$v1 <- with(df, na.locf(replace(v1, v1=="", NA)))
df$v1
#[1] "2"  "2"  "2"  "2"  "3"  "3"  "4"  "4"  "4"  "OT"

这也可以用 base R 来完成,方法是创建一个分组变量,然后用 ave

填充它
with(df,  ave(v1, cumsum(v1!=""), FUN = function(x) x[1]))
#[1] "2"  "2"  "2"  "2"  "3"  "3"  "4"  "4"  "4"  "OT"