首页 > 解决方案 > 如果另一个变量的下一行满足条件,则定义新变量取 1

问题描述

所以我正在尝试为事件历史分析设置我的数据集,为此我需要定义一个新列。我的数据集具有以下形式:

ID   Var1
1    10
1    20  
1    30  
1    10
2    4
2    5
2    10
2    5
3    1
3    15
3    20
3    9
4    18
4    32
4    NA
4    12
5    2
5    NA
5    8
5    3

我想得到以下表格:

ID   Var1   Var2
1    10      0
1    20      0
1    30      1
1    10      0
2    4       0
2    5       0
2    10      0
2    5       0
3    1       0
3    15      0
3    20      1
3    9       0
4    18      0
4    32      NA
4    NA      1
4    12      0
5    2       NA
5    NA      0
5    8       1
5    3       0

所以用文字来说:我希望新变量表明,如果Var1(相对于组)的值低于该Var1组达到的最大值的 50%。最后一个值是 NA 还是 0 并不重要,尽管NA从理论角度来看会更有意义。我试过使用类似的东西

DF$Var2 <- df %>%
  group_by(ID) %>%
  ifelse(df == ave(df$Var1,df$ID, FUN = max), 0,1)

然后将其滞后 1,但它在 ifelse 中未使用的参数 1 上返回错误。

感谢您的解决方案!

标签: rif-statementplyrcalculated-columns

解决方案


这是通过ave+的基本 R 选项cummax

within(df,Var2 <- ave(Var1,ID,FUN = function(x) c((x<max(x)/2 & cummax(x)==max(x))[-1],0)))

这使

> within(df,Var2 <- ave(Var1,ID,FUN = function(x) c((x<max(x)/2 & cummax(x)==max(x))[-1],0)))
   ID Var1 Var2
1   1   10    0
2   1   20    0
3   1   30    1
4   1   10    0
5   2    4    0
6   2    5    0
7   2   10    0
8   2    5    0
9   3    1    0
10  3   15    0
11  3   20    1
12  3    9    0

数据

> dput(df)
structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L), Var1 = c(10L, 20L, 30L, 10L, 4L, 5L, 10L, 5L, 1L, 15L,
20L, 9L)), class = "data.frame", row.names = c(NA, -12L))

编辑(更新后的帖子)

f <- function(v) {
  u1 <- c(replace(v,!is.na(v),0),0)[-1]
  v[is.na(v)] <- v[which(is.na(v))-1]
  u2 <- c((v<max(v)/2 & cummax(v)==max(v))[-1],0)
  u1+u2
}

within(df,Var2 <- ave(Var1,ID,FUN = f))

这样

> within(df,Var2 <- ave(Var1,ID,FUN = f))
   ID Var1 Var2
1   1   10    0
2   1   20    0
3   1   30    1
4   1   10    0
5   2    4    0
6   2    5    0
7   2   10    0
8   2    5    0
9   3    1    0
10  3   15    0
11  3   20    1
12  3    9    0
13  4   18    0
14  4   32   NA
15  4   NA    1
16  4   12    0
17  5    2   NA
18  5   NA    0
19  5    8    1
20  5    3    0

数据

df <- tructure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L,    
3L, 3L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L), Var1 = c(10L, 20L, 30L, 
10L, 4L, 5L, 10L, 5L, 1L, 15L, 20L, 9L, 18L, 32L, NA, 12L, 2L,   
NA, 8L, 3L)), class = "data.frame", row.names = c(NA, -20L))   

推荐阅读