在 Data.Table 的 dcast 中使用比例作为聚合函数
Using proportion as the aggregate function in Data.Table's dcast
使用 data.table 创建数据透视表 table 时,我使用的是 dcast 函数:
dcast(my_data, var1 ~ var2, length)
这给出了一个 table,其中行作为 var1 标签,列作为 var2 标签,值作为特定行和列共有的单元格计数。
但是我想计算比例并将其作为值,而不是长度,即{特定行和列共有的单元格数}除以{列中所有单元格的计数,即 var2 的特定级别}
我已经搜索过了,无法实现。
任何帮助将不胜感激。
有一个相对简单的解决方案,但是在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
然后您可以简单地遍历所有列并将列中的每个元素除以列中所有值的总和。
Select 要转换的列:
cols <- unique(my_data$var2)
在 .SDcols
中指定的列子集上使用 lapply()
遍历列并覆盖所有 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
如果我们需要按行比例
,我们可以将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))
使用 data.table 创建数据透视表 table 时,我使用的是 dcast 函数:
dcast(my_data, var1 ~ var2, length)
这给出了一个 table,其中行作为 var1 标签,列作为 var2 标签,值作为特定行和列共有的单元格计数。
但是我想计算比例并将其作为值,而不是长度,即{特定行和列共有的单元格数}除以{列中所有单元格的计数,即 var2 的特定级别}
我已经搜索过了,无法实现。 任何帮助将不胜感激。
有一个相对简单的解决方案,但是在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
然后您可以简单地遍历所有列并将列中的每个元素除以列中所有值的总和。
Select 要转换的列:
cols <- unique(my_data$var2)
在 .SDcols
中指定的列子集上使用 lapply()
遍历列并覆盖所有 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
如果我们需要按行比例
,我们可以将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))