计算R中data.table两列之间转移概率的干净方法

计算R中data.table两列之间转移概率的干净方法,r,data.table,probability,R,Data.table,Probability,玩具示例: library(data.table) set.seed(1) n_people <- 100 groups <- c("A", "B", "C") example_table <- data.table(person_id=seq_len(n_people), group_2010=sample(groups, n_people, TRUE), gro

玩具示例:

library(data.table)

set.seed(1)
n_people <- 100
groups <- c("A", "B", "C")
example_table <- data.table(person_id=seq_len(n_people),
                            group_2010=sample(groups, n_people, TRUE),
                            group_2011=sample(groups, n_people, TRUE))

## Error-prone and requires lots of typing -- programmatic alternative?
transition_probs <- example_table[, list(pr_A_2011=mean(group_2011=="A"),
                                         pr_B_2011=mean(group_2011=="B"),
                                         pr_C_2011=mean(group_2011=="C")),
                                         by=group_2010]
transition_probs  # Essentially a transition matrix giving Pr[group_2011 | group_2010]

#    group_2010 pr_A_2011 pr_B_2011 pr_C_2011
# 1:          A 0.1481481 0.5185185 0.3333333
# 2:          B 0.3684211 0.3947368 0.2368421
# 3:          C 0.3142857 0.3142857 0.3714286
库(data.table)
种子(1)
n_人们我会的

lvls = example_table[, sort(unique(c(group_2010, group_2011))) ]
x = dcast(example_table, group_2010~group_2011)[, N := Reduce(`+`,.SD), .SDcols=lvls]

#    group_2010  A  B  C  N
# 1:          A  6  9 15 30
# 2:          B 15  4 12 31
# 3:          C 11 11 17 39
从这里开始,如果需要转移概率,只需除以
N

x[, (lvls) := lapply(.SD,`/`, x$N), .SDcols=lvls]
# or, with data.table 1.9.7+
x[, (lvls) := lapply(.SD,`/`, N), .SDcols=lvls]

#    group_2010         A         B         C  N
# 1:          A 0.1481481 0.5185185 0.3333333 27
# 2:          B 0.3684211 0.3947368 0.2368421 38
# 3:          C 0.3142857 0.3142857 0.3714286 35

data.table
的设计有意与
data.frames
上的操作兼容,因此除非您能够(a)证明此操作是一个巨大的瓶颈,(b)证明替代解决方案的速度明显更快,否则为什么不坚持简洁明了:

prop.table(table(example_table[,2:3,with=FALSE]),1)
集团2011 2010年A组B组C组 A 0.1481481 0.5185185 0.3333333 B 0.3684211 0.3947368 0.2368421 C 0.3142857 0.3142857 0.3714286
我认为目前的两个答案都很好地解决了你的问题。我将回答,然后以更一般的方式进行处理。
如果您想要真正的编程能力,可以使用R语言功能

R属于一类程序设计语言,其中子程序能够修改或构造其他子程序,并将结果作为语言本身的一个组成部分进行计算

库(data.table)
种子(1)
n_人们谢谢你--我其实不知道关于道具表的事!
group_2011
group_2010         A         B         C
         A 0.1481481 0.5185185 0.3333333
         B 0.3684211 0.3947368 0.2368421
         C 0.3142857 0.3142857 0.3714286
library(data.table)
set.seed(1)
n_people <- 100
groups <- c("A", "B", "C")
example_table <- data.table(person_id=seq_len(n_people),
                            group_2010=sample(groups, n_people, TRUE),
                            group_2011=sample(groups, n_people, TRUE))
f = function(data, groups, years) {
    stopifnot(is.data.table(data), length(groups) > 0L, length(years) == 2L, paste0("group_", years) %in% names(data))
    j.names = sprintf("pr_%s_%s", c(groups), years[2L])
    j.vals = lapply(setNames(groups, j.names), function(group) call("mean", call("==", as.name(sprintf("group_%s", years[2L])), group)))
    jj = as.call(c(list(as.name(".")), j.vals))
    data[, eval(jj), by = c(sprintf("group_%s", years[1L]))]
}
f(example_table, groups, 2010:2011)
#   group_2010 pr_A_2011 pr_B_2011 pr_C_2011
#1:          A 0.1481481 0.5185185 0.3333333
#2:          B 0.3684211 0.3947368 0.2368421
#3:          C 0.3142857 0.3142857 0.3714286