计算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