【问题标题】:Define new variable to take on 1 if next row of another variable fulfills condition如果另一个变量的下一行满足条件,则定义新变量取 1
【发布时间】:2020-11-18 18:53:23
【问题描述】:

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

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 上返回错误。

感谢您的解决方案!

【问题讨论】:

  • 您的预期输出是否正确?试试df %&gt;% group_by(ID) %&gt;% mutate(Var2 = as.integer(Var1 &gt; 0.5*max(Var1)))

标签: r if-statement plyr calculated-columns


【解决方案1】:

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

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))   

【讨论】:

  • 非常感谢您的回答,它给出了预期的结果。但是有一个问题:某些组在 Var1 中包含一些 NA,如果有一个 NA,则代码将完整的 Var2 列返回为 NA。我尝试使用 ifelse 语句解决它,但它一直返回错误。有没有简单直接的方法来解决这个问题?
  • @philipp.kn_98 欢迎您。您能否提供一个在 Var1 中具有 NA 以及预期结果的小示例?那我再试一次
  • 刚刚编辑了问题以提供信息。到目前为止发生的情况是,代码为第 4 组和第 5 组中的整个列返回 NA,而所需的输出只是将 NA 向上移动了一行(所问的问题是合乎逻辑的:下一行的得分是否低于 XY 阈值?) .谢谢你的努力!!
  • @philipp.kn_98 你能解释一下为什么Var2ID=4ID = 5 是这样的吗?我不知道它的逻辑。比如ID = 4时,Var1 = 32行给出Var2 = NA,但是为什么下一行有Var1 = NAVar2 = 1呢?
  • @philipp.kn_98 我更新了我的答案,请检查是否适合你
猜你喜欢
  • 2021-07-16
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-13
  • 2020-11-25
  • 2019-06-05
  • 1970-01-01
相关资源
最近更新 更多