reshape2 dcast - fun.aggregate 列表中的值

reshape2 dcast - values in fun.aggregate tabulate

我想列一个长表data.frame。以下示例代码创建了一个长 data.frame,包含列 "ID"、"unit" 和 "mat"。使用 dcast 我想创建一个宽格式 data.frame,每个 "mat" 都有新的列,值应该是 1(这个组合存在)或 0(不,不存在......)。

df.long <- data.frame(ID = c(3, 4, 8, 9, 3, 4, 10, 3, 3, 4),
    unit = c("cm", "cm", "m", "K", "cm", "cm", "m", "cm", "m", "cm"),
    mat = c(1,1,1,1,2,2,2,3,3,3))
dcast(df.long, ID + unit ~ mat)

给我一个如下所示的数据框:

ID unit  1  2  3
1  3   cm  1  2  3
2  3    m NA NA  3
3  4   cm  1  2  3
4  8    m  1 NA NA
5  9    K  1 NA NA
6 10    m NA  2 NA

要让 table 填充 1 和 0(按计划),我现在找到的唯一方法是向长 data.frame 添加一个附加列并使用 "fun.aggregate = tabulate"作为额外的 dcast 参数,即:

df.long <- data.frame(ID = c(3, 4, 8, 9, 3, 4, 10, 3, 3, 4),
    unit = c("cm", "cm", "m", "K", "cm", "cm", "m", "cm", "m", "cm"),
    mat = c(1,1,1,1,2,2,2,3,3,3),
    value = c(1,1,1,1,1,1,1,1,1,1))
dcast(df.long, ID + unit ~ mat, fun.aggregate = tabulate)

ID unit 1 2 3
1  3   cm 1 1 1
2  3    m 0 0 1
3  4   cm 1 1 1
4  8    m 1 0 0
5  9    K 1 0 0
6 10    m 0 1 0

尽管它现在按预期工作,但我想知道是否有人有更好的方法,只使用 dcast 功能,而不改变初始 data.frame。

我认为这样做可以:

dcast(df.long, ID + unit ~ mat, 
      fill = 0, 
      fun.aggregate = function(x) 1)
#  ID unit 1 2 3
#1  3   cm 1 1 1
#2  3    m 0 0 1
#3  4   cm 1 1 1
#4  8    m 1 0 0
#5  9    K 1 0 0
#6 10    m 0 1 0

Roland 的方法确实有效,但简单地使用 as.logical 作为聚合函数可能更有意义:

dcast(df.long, ID + unit ~ mat, 
      fill = 0, 
      fun.aggregate = as.logical, 
      value.var =  "mat")
#   ID unit 1 2 3
# 1  3   cm 1 1 1
# 2  3    m 0 0 1
# 3  4   cm 1 1 1
# 4  8    m 1 0 0
# 5  9    K 1 0 0
# 6 10    m 0 1 0

尝试 as.logical(-1:3) 了解什么被转换为零,什么被转换为一。