创建 Winner/Looser 应急方案的有效方法 - Table

Efficient way to create a Winner/Looser Contingency-Table

我对 R 比较陌生,需要一些帮助。

我想生成一个 2x2 的意外事件 table 并且始终按如下方式比较连续两天:从第一行开始并取值的中位数,在我的示例中是 2019-02- 行11 它将是 x4 的值 15。现在所有高于中位数的值都是 "winners",低于中位数的值是 "losers".

在第二步中,您对行 2019-02-12 执行相同的操作,例如,如果 x1 在两个期间都为 "winner",则它应该计入意外事件中的字段 "winner/winner" table。对于所有连续的日期,"loser/loser"、"winner/loser"、"loser/winner" 等也是如此。

我有一个包含大约 200 列的数据框,因此正在寻找一种有效的方法来执行此操作。

我的代码如下所示:

            set.seed(123)
            d <- data.frame(Time = rep(seq.Date( Sys.Date(), length=30, by="day" )),
            x1 = rep(sample(10:30, 10), 3),
            x2 = rep(sample(10:30, 10), 3),
            x3 = rep(sample(10:30, 10), 3),
            x4 = rep(sample(10:30, 10), 3),
            x5 = rep(sample(10:30, 10), 3))

非常感谢。

通过一些算术,我认为我们可以非常有效地做到这一点。

首先,我们找到赢家和输家,并相应地为他们分配 01。接下来,我们可以进行逐列差分,以确定连续两天是 lose/win (1) 还是输赢 (-1)。由于 win/win 和 lose/lose 都会导致差值为零,因此我们还必须检查第一个值是什么。剩下的只是重新编码和组装。

d <- structure(list(Time=structure(17942:17947, class="Date"),
x1=c(NA, NA, 17L, 29L, 27L, 10L), x2=c(30L, 19L, 22L, 20L, 11L,
24L), x3=c(NA, 23L, 22L, 27L, 21L, 26L), x4=c(30L, 28L, 23L,
24L, 10L, 17L), x5=c(12L, 18L, 17L, 16L, 30L, 26L)),
row.names=c(NA, 6L), class="data.frame")

x <- t(apply(d[,-1], 1, function(x) x > median(x, na.rm=TRUE)))
nr <- nrow(x)
dx <- diff(x)

lw <- (dx == 1)*1
wl <- (dx == -1)*2
dd <- (dx == 0)
ww <- (dd & x[-nr,] == 1)*3
ll <- (dd & x[-nr,] == 0)*4

tab <- c("lose/win", "win/lose", "win/win", "lose/lose")[lw + wl + ww + ll]

d0 <- d
d0[-1,-1] <- tab
d0

#         Time       x1        x2       x3        x4        x5
# 1 2019-02-15     <NA>        30     <NA>        30        12
# 2 2019-02-16     <NA> lose/lose     <NA>  lose/win lose/lose
# 3 2019-02-17     <NA> lose/lose win/lose   win/win lose/lose
# 4 2019-02-18 lose/win lose/lose lose/win  win/lose lose/lose
# 5 2019-02-19  win/win lose/lose win/lose lose/lose  lose/win
# 6 2019-02-20 win/lose lose/lose lose/win lose/lose   win/win