通过另一行的因子值更改行中的因子值

时间:2015-06-23 09:58:45

标签: r dataframe

这是一个示例数据框

df <- data.frame(v1=factor(c("empty","a","empty","c","b")),
                 v2=factor(c("empty","z","z","y","x")))

如果非空,我现在想要替换emptyv1的值 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分钟)。

出于各种原因,我希望保持因子水平而不想更改为数字。

2 个答案:

答案 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]