因子变量的累积和

时间:2016-04-11 21:51:13

标签: r dataframe

我正在尝试在R中创建一组累积因子变量。我df有4个时刻的治疗假人:

id t1 t2 t3 t4 
1   0  0  0  1 
2   1  0  0  0
3   0  0  0  1
4   0  1  0  0
5   1  0  0  0

我想要的是一组累积治疗变量(在下面的例子中命名为tc),如下所示:

id tc1 tc2 tc3 tc4 
1   0  0  0  1 
2   1  1  1  1
3   0  0  0  1
4   0  1  1  1
5   1  1  1  1

我尝试了cumsum函数,但我不知道如何处理因子变量的这个函数。知道如何做到这一点?

2 个答案:

答案 0 :(得分:4)

一种方法是尝试matrixStats::rowCummaxs功能,但您需要先转换为matrix。但是,根据您的数据结构判断,我建议首先使用matrix代替data.frame

data1[-1] <- matrixStats::rowCummaxs(as.matrix(data1[-1]))
data1
#   id t1 t2 t3 t4
# 1  1  0  0  0  1
# 2  2  1  1  1  1
# 3  3  0  0  0  1
# 4  4  0  1  1  1
# 5  5  1  1  1  1

或者行方法apply(也转换为matrix

data1[-1] <- t(apply(data1[-1], 1, cummax))

或者@joran暗示 - 我们可以尝试长/宽转换

library(data.table)
dcast(melt(setDT(data1), 
           id = "id"
           )[, value := cummax(value),
             by = id], 
      id ~ variable)

#    id t1 t2 t3 t4
# 1:  1  0  0  0  1
# 2:  2  1  1  1  1
# 3:  3  0  0  0  1
# 4:  4  0  1  1  1
# 5:  5  1  1  1  1

或者

library(dplyr)
library(tidyr)
data1 %>%
  gather(variable, value, -id) %>%
  group_by(id) %>%
  mutate(value = cummax(value)) %>%
  spread(variable, value)

# Source: local data frame [5 x 5]
# Groups: id [5]
# 
#      id    t1    t2    t3    t4
#   (int) (int) (int) (int) (int)
# 1     1     0     0     0     1
# 2     2     1     1     1     1
# 3     3     0     0     0     1
# 4     4     0     1     1     1
# 5     5     1     1     1     1

或@alexis_laz使用pmax每行累积Reduce的有趣替代方案

data1[-1] <- Reduce(pmax, data1[-1], accumulate = TRUE)
data1
#   id t1 t2 t3 t4
# 1  1  0  0  0  1
# 2  2  1  1  1  1
# 3  3  0  0  0  1
# 4  4  0  1  1  1
# 5  5  1  1  1  1

答案 1 :(得分:3)

max.col救援:

df[-1][col(df[-1]) >= max.col(df[-1], ties.method="first")] <- 1
df

#  id t1 t2 t3 t4
#1  1  0  0  0  1
#2  2  1  1  1  1
#3  3  0  0  0  1
#4  4  0  1  1  1
#5  5  1  1  1  1

以及如何运作的更详细解释:

col(df[-1])
#     [,1] [,2] [,3] [,4]
#[1,]    1    2    3    4
#[2,]    1    2    3    4
#[3,]    1    2    3    4
#[4,]    1    2    3    4
#[5,]    1    2    3    4

max.col(df[-1], ties.method="first")
#[1] 4 1 4 2 1

col(df[-1]) >= max.col(df[-1], ties.method="first")
#      [,1]  [,2]  [,3] [,4]
#[1,] FALSE FALSE FALSE TRUE
#[2,]  TRUE  TRUE  TRUE TRUE
#[3,] FALSE FALSE FALSE TRUE
#[4,] FALSE  TRUE  TRUE TRUE
#[5,]  TRUE  TRUE  TRUE TRUE