【问题标题】:Make the `drop` argument in `dcast` only look at the RHS of the formula让 `dcast` 中的 `drop` 参数只看公式的 RHS
【发布时间】:2016-04-22 05:13:59
【问题描述】:

dcast 中的 drop 参数(来自“reshape2”或“dplyr”)在从“长”数据集到“宽”数据集时非常有用,并且您想要创建列,即使组合不以长形式存在。

事实证明,使用 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

如果 LHS 上有多个值,则 LHS 上的值的组合也会被展开,就像我们使用了 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,我想过这个问题,但我不喜欢可能丢失数据保真度、缺少在 LHS 上使用 ... 的选项以及丢失列名.
  • 一个可能的解决方案可能是在drop 中允许双重逻辑。类似于drop = c(TRUE, FALSE),其中第一个适用于 RHS,第二个适用于 LHS。
  • 听起来很有趣@Jaap。有模拟实现吗? ;-)
  • feature request for data.table 的身份在 GH 上发布。

标签: r data.table reshape reshape2


【解决方案1】:

刚刚在data.table开发版本v1.9.7中实现,commit 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

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多