使用data.table创建数据透视表时,我使用的是dcast函数:
dcast(my_data, var1 ~ var2, length)
这给出了一个表,其中行为var1标签,列为var2标签,值为特定行和列共有的单元格数。
但不是长度,我想计算比例并将其作为值,即{特定行和列共有的单元格数}除以{列中所有单元格的数量,即特定的var2级别} < / p>
我搜索过但无法实现它。 任何帮助将不胜感激。
答案 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))