基于当前上一个和下一个值的新变量的R规则

时间:2019-06-14 17:17:35

标签: r dplyr tidyverse

数据

data=data.frame("person"=c(1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4),
                 "score"=c(1,2,1,3,4,3,1,2,1,3,1,2,3,1,3,2,2,3,1,3,3),
                  "want"=c(1,1,1,3,4,1,1,1,1,1,1,1,1,1,1,3,1,1,1,3,3))

我会在这里尽力解释我希望实现的目标。

基本上我想创建一个'want'列,该列取决于上一个,当前和下一个值。

在数据中,个人的得分为1,2,3,4。我想要一个遵循以下规则的新变量“想要”:

  1. 如果在时间T-1得分为3,而在时间T + 1得分为2或3,则在时间T得分为3。
  2. 如果在时间T得分为3,在时间T + 1得分为4,则在时间T得分为3。
  3. 否则,所有分数均应为1,除非存在4。

2 个答案:

答案 0 :(得分:2)

是否应该看起来像您的want列?这会产生不同的结果,但似乎遵循您的逻辑:

library(dplyr)
data %>% 
  group_by(person) %>% 
  mutate(want2 = case_when(
    (lag(score) == 3 & lead(score) %in% c(2,3)) ~ 3,
    score == 3 & lead(score) == 4 ~ 3,
    T ~ 1))

答案 1 :(得分:0)

您想要的列不遵循您自己的规则。请注意,您在第5位有4,但没有规则指定4(根据您的规则,其他值似乎计算错误)。

# load packages
library(data.table)

# create data
dt <- data.table(person = c(1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4),
                 score = c(1,2,1,3,4,3,1,2,1,3,1,2,3,1,3,2,2,3,1,3,3))

# Make lead and lag vectors
dt[, tMinus := shift(score, 1, type = "lag")]
dt[, tPlus := shift(score, 1, type = "lead")]

# calculate want
dt[, want := 1][tMinus == 3 & tPlus %in% 2:3, want := 3][score == 3 & tPlus == 4, want := 3]

# remove unneeded columns
dt[, c("tMinus", "tPlus") := NULL]

这将产生结果:

> dt
    person score want
 1:      1     1    1
 2:      1     2    1
 3:      1     1    1
 4:      1     3    3
 5:      1     4    3
 6:      2     3    1
 7:      2     1    3
 8:      2     2    1
 9:      2     1    1
10:      2     3    1
11:      2     1    3
12:      3     2    1
13:      3     3    1
14:      3     1    3
15:      3     3    1
16:      3     2    3
17:      4     2    1
18:      4     3    1
19:      4     1    3
20:      4     3    1
21:      4     3    1
    person score want

尚不清楚您是否要按want计算person。如果是这样,请考虑下一个代码:

dt[, tPlus := shift(score, 1, type = "lead"), by = person]
dt[, tMinus := shift(score, 1, type = "lag"), by = person]
dt[, want := 1][tMinus == 3 & tPlus %in% 2:3, 
                want := 3][score == 3 & tPlus == 4, 
                           want := 3][, 
          c("tMinus", "tPlus") := NULL][]