使`dcast`函数中的`drop`参数仅查看公式右侧。

19

dcast(来自“reshape2”或“dplyr”)中的drop参数在从“长格式”转换为“宽格式”数据集时非常有用,您希望即使在长格式中不存在的组合也创建列。

事实证明,使用drop还会影响公式左侧(LHS)和右侧(RHS)的组合。因此,它还会基于LHS值的组合创建额外的

是否有一种方法可以覆盖这种行为?


这里是一些样本数据:

library(data.table)
DT <- data.table(v1 = c(1.105, 1.105, 1.105, 2.012, 2.012, 2.012),
                 ID = c(1L, 1L, 1L, 2L, 2L, 2L), 
                 v2 = structure(c(2L, 3L, 5L, 1L, 2L, 6L), 
                                .Label = c("1", "2", "3", "4", "5", "6"), 
                                class = "factor"),
                 v3 = c(3L, 2L, 2L, 5L, 4L, 3L)) 

注意,“v2”是一个具有6个级别的factor列。本质上,我希望从“长”变为“宽”,但要添加任何缺失的因子级别列(在本例中为“4”)。

reshape处理形状,但不处理缺失的列:

reshape(DT, direction = "wide", idvar = c("ID", "v1"), timevar = "v2")
#       v1 ID v3.2 v3.3 v3.5 v3.1 v3.6
# 1: 1.105  1    3    2    2   NA   NA
# 2: 2.012  2    4   NA   NA    5    3

dcast处理添加缺失的列,但仅在LHS上有一个值时才处理:

dcast(DT, ID ~ v2, value.var = "v3", drop = FALSE)
#    ID  1 2  3  4  5  6
# 1:  1 NA 3  2 NA  2 NA
# 2:  2  5 4 NA NA NA  3

如果左侧有多个值,则左侧值的组合也会被展开,就像我们使用了CJexpand.grid一样,但第2行和第3行对我来说没有任何意义:

dcast(DT, ... ~ v2, value.var = "v3", drop = FALSE)
#       v1 ID  1  2  3  4  5  6
# 1: 1.105  1 NA  3  2 NA  2 NA
# 2: 1.105  2 NA NA NA NA NA NA
# 3: 2.012  1 NA NA NA NA NA NA
# 4: 2.012  2  5  4 NA NA NA  3

这类似于在基本R中使用xtabsftable(xtabs(v3 ~ ID + v1 + v2, DT))


有没有一种方法能让dcast知道,本质上,“嘿,LHS值的组合是ID,请不要尝试为我填充它们。”

我的当前方法是进行三个步骤,一个用于折叠LHS值,另一个用于展开RHS值,然后再进行合并。

merge(DT[, list(v1 = unique(v1)), .(ID)],  ## or unique(DT[, c("ID", "v1"), with = FALSE])
      dcast(DT, ID ~ v2, value.var = "v3", drop = FALSE), 
      by = "ID")[]
#    ID    v1  1 2  3  4  5  6
# 1:  1 1.105 NA 3  2 NA  2 NA
# 2:  2 2.012  5 4 NA NA NA  3

我是否错过了更好的方法?


类似这样的代码(也许):dcast(DT, interaction(v1,ID,drop=TRUE) ~ v2, value.var = "v3", drop = FALSE)。但是你需要在之后拆分第一列。 - nicola
@nicola,我考虑过这个问题,但我不喜欢数据保真度可能会降低、无法在左侧使用...选项以及列名称丢失的情况。 - A5C1D2H2I1M1N2O1R2T1
1
一个可能的解决方案是在 drop 中允许双逻辑。例如 drop = c(TRUE, FALSE),其中第一个适用于 RHS,第二个适用于 LHS。 - Jaap
听起来很有趣,@Jaap。有模拟实现吗?;-) - A5C1D2H2I1M1N2O1R2T1
1
在 GH 上发布了一个关于 data.table 的功能请求(https://github.com/Rdatatable/data.table/issues)。 - Jaap
1个回答

9

在data.table开发版本v1.9.7中刚刚实现,提交2113,关闭#1512问题。

require(data.table) # v1.9.7, commit 2113+
dcast(DT, ... ~ v2, value.var = "v3", drop = c(TRUE, FALSE))
#       v1 ID  1 2  3  4  5  6
# 1: 1.105  1 NA 3  2 NA  2 NA
# 2: 2.012  2  5 4 NA NA NA  3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接