使用比例作为Data.Table的dcast中的聚合函数

时间:2018-04-05 05:43:29

标签: r data.table dcast

使用data.table创建数据透视表时,我使用的是dcast函数:

dcast(my_data, var1 ~ var2, length)

这给出了一个表,其中行为var1标签,列为var2标签,值为特定行和列共有的单元格数。

但不是长度,我想计算比例并将其作为值,即{特定行和列共有的单元格数}除以{列中所有单元格的数量,即特定的var2级别} < / p>

我搜索过但无法实现它。 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

有一个相对简单的解决方案,但它需要在dcast()之后的第二步。

首先,这是我正在处理的数据:

library(data.table)

set.seed(666)
my_data <- data.table(var1 = sample(letters[1:3], 10, TRUE),
                      var2 = sample(letters[4:6], 10, TRUE))

    var1 var2
 1:    c    f
 2:    a    d
 3:    c    d
 4:    a    d
 5:    b    d
 6:    c    f
 7:    c    d
 8:    b    f
 9:    a    e
10:    a    e

dcast之后

my_data_dcast <- dcast(my_data, var1 ~ var2, length)

数据如下所示:

   var1 d e f
1:    a 2 2 0
2:    b 1 0 1
3:    c 2 0 2

然后,您可以简单地遍历所有列,并将列中的每个元素除以列中所有值的总和。

选择要转换的列:

cols <- unique(my_data$var2)

lapply()中指定的列子集上使用.SDcols浏览列,并覆盖所有cols的值:

my_data_dcast[, (cols) := (lapply(.SD, function(col) col / sum(col))),
              .SDcols = cols]

最终结果如下:

   var1   d e         f
1:    a 0.4 1 0.0000000
2:    b 0.2 0 0.3333333
3:    c 0.4 0 0.6666667

答案 1 :(得分:1)

如果我们需要行比例

,我们可以将Reduce+一起使用
dcast(my_data, var1~ var2, length)[, .SD/Reduce(`+`, .SD), var1]
#   var1         A         B         C    D
#1:    a 0.3750000 0.0000000 0.3750000 0.25
#2:    b 0.6000000 0.2000000 0.2000000 0.00
#3:    c 0.2857143 0.1428571 0.5714286 0.00

如果我们需要列式

dcast(my_data, var1~ var2, length)[, .SD, var1][, 
        (2:5) := Map(`/`, .SD, colSums(.SD)), .SDcols = -1][]
#   var1     A   B     C D
#1:    a 0.375 0.0 0.375 1
#2:    b 0.375 0.5 0.125 0
#3:    c 0.250 0.5 0.500 0

base R

会更紧凑
prop.table(table(my_data), 1)
prop.table(table(my_data), 2)

数据

set.seed(24)
my_data <- data.table(var1 = sample(letters[1:3], 20, replace = TRUE),
           var2 = sample(LETTERS[1:4], 20, replace = TRUE))