这是一个示例数据框
df <- data.frame(v1=factor(c("empty","a","empty","c","b")),
v2=factor(c("empty","z","z","y","x")))
如果非空,我现在想要替换empty
中v1
的值
v2
中的模拟。
在此示例中,z
中的v2
映射到第二行a
中的v1
。
因此,第三行中的empty
也应为a
。
因此,最终数据框应为:
df.final <- data.frame(v1=factor(c("empty","a","a","c","b")),
v2=factor(c("empty","z","z","y","x")))
改变这个的解决方案是什么? 我用两个嵌套的for循环尝试了它,但这需要永远(对于我的数据框架有25000行和几千个因子级别约15分钟)。
出于各种原因,我希望保持因子水平而不想更改为数字。
答案 0 :(得分:4)
一种选择是将“空”字符串更改为“NA”,然后使用na.locf
将“NA”值替换为非NA之前的值。
library(zoo)
is.na(df) <- df=='empty'
df[] <- lapply(df, na.locf, na.rm=FALSE)
或者@DavidArenburg建议,如果只有'字符'列,您可以直接在数据集上应用na.locf
,否则,可能需要对数据集进行子集化。如果初始列是'factor'类,即使输出是'data.frame',它也会转换为'character'
df[] <- na.locf(df, na.rm=FALSE)
如果你想以“空”的形式返回(最好保留为'NA'值)
df[] <- lapply(df, function(x) {x1 <- na.locf(x, na.rm=FALSE)
replace(x1, which(is.na(x1)), 'empty') })
答案 1 :(得分:3)
这是一个可能的data.table
解决方案(我假设v1
中每个值v2
都有一个唯一值 - 如果我错了,请纠正我)。在这里,我尝试仅使用v2
使用负二进制连接的empty
值进行操作来减少问题,而通过引用分配使用:=
运算符
library(data.table)
setkey(setDT(df), v2)
df[!J("empty"), v1 := v1[v1 != "empty"][1L], by = v2]
修改强>
与实际数据集选项更加一致的可能是
df[!J("empty"), v1 := replace(v1, v1 == "empty", v1[v1 != "empty"][1L]), by = v2]