2

如何使用 sqldf 在左连接中保留因子变量?

我正在尝试使用 R 中的 sqldf 函数执行左连接;但是,该过程似乎将我的“正确”数据框中的因子列转换为合并数据集中的字符类。

我怀疑这是因为左连接包括来自“左”数据帧的行,而“右”数据帧中没有相应的行,因此将 NA 引入了因子列。

我创建了这个可重现的示例:

require(sqldf)
leftDF <- data.frame(A = sample(1:15, replace = FALSE), 
                     B = sample(letters, 15, replace = TRUE),
                     stringsAsFactors = FALSE)
str(leftDF)
rightDF <- data.frame(X = sample(1:5, 10, replace = TRUE),
                      Y = sample(letters, 10, replace = TRUE),
                      stringsAsFactors = TRUE)
str(rightDF)
mergedDF <- sqldf("SELECT l.A, l.B, r.Y 
                   FROM leftDF as l 
                   LEFT JOIN rightDF as r 
                   ON l.A = r.X")
str(mergedDF)

这是 sqldf 的预期行为吗?将因式变量转换为字符类对程序员来说可能并不明显,除非该变量在未来的分析中表现得不像他们所期望的那样。

我可以通过在使用 addNA(); 加入之前首先向分解列添加一个 NA 级别来保留因子;但是,似乎不鼓励将 NA 添加为级别(请参阅 ?addNA 中的警告)。有没有更好的方法来处理这个?

提前致谢,

杰夫

解决评论的另一个示例:

require(sqldf)
leftDF <- data.frame(A = sample(1:15, replace = FALSE),
                     B = sample(letters, 15, replace = TRUE), 
                     stringsAsFactors = FALSE)
str(leftDF)
rightDF <- data.frame(X = sample(1:5, 10, replace = TRUE),
                      Y = sample(c("one","two","three","four","five","six"), 
                                 10, replace = TRUE), stringsAsFactors = FALSE)
rightDF$Y <- factor(rightDF$Y, levels = c("one","two","three","four","five","six"))
#rightDF$Y <- addNA(rightDF$Y)
table(rightDF$Y)
str(rightDF)
mergedDF <- sqldf("SELECT l.A, l.B, r.Y as Y__factor
                   FROM leftDF as l
                   LEFT JOIN rightDF as r
                   ON l.A = r.X")
str(mergedDF)
table(mergedDF$Y, useNA = c("always"))
4

2 回答 2

1

这是sqldf 主页上的常见问题解答 #1

在这种情况下, 的组件mergeDF$Y并非全部在 的级别中,rightDF$Y因此它不能使用后者的级别,因此恢复为使用"character"类。

可以通过method多种方式使用参数来指定结果。见?sqldf

sqldf或者在声明之后修复它。

这是一个例子:

# use one of the next two lines or some further variation depending on what you want
meth <- function(x) replace(x, "Y", factor(x$Y, levels(rightDF$Y)))
meth <- function(x) replace(x, "Y", factor(x$Y, c(levels(rightDF$Y), NA), exclude=NULL))

mergedDF <- sqldf("SELECT l.A, l.B B, r.Y
                   FROM leftDF as l 
                   LEFT JOIN rightDF as r 
                   ON l.A = r.X", method = meth) ## note use of method=meth
于 2013-10-24T18:27:00.883 回答
0

刚刚(并解决了)在 R 中使用“sqldf”选择的类似问题。我所有的变量都保持不变(因子保持因子,字符保持字符等等),但是对于我的一个有序因子变量,它变成了一个字符多变的。

检查过,这是我唯一缺少值的变量。所以我让缺失值成为一个因素,问题解决了,在“sqldf”选择之后变量保持不变:-)希望它有帮助!

于 2018-04-23T21:02:31.487 回答