复杂条件变异:使用条件变异创建新变量,仅使用给定参与者的过去观察?

时间:2018-03-21 20:30:35

标签: r dplyr stata case-when mutate

我有一个数据框(fbwb),在一组参与者中使用多个度量(1-3)对欺凌(1-6)进行多次评估。 df看起来像这样:

fbwb <- read.table(text="id year bully1 bully2 bully3 cbully bully_ever 
100 1 NA 1 NA 1 1
100 2 1 1 NA 1 1
100 3 NA 0 NA 0 1
101 1 NA NA 1 1 1
102 1 NA 1 NA 1 1
102 2 NA NA NA NA 1
102 3 NA 1 1 1 1
102 4 0 0 0 0 1
103 1 NA 1 NA 1 1
103 2 NA 0 0 0 1", header=TRUE)

其中bully1,bully2和bully3是二进制变量,如果在相应的度量上报告了欺凌,则每个变量= 1。 如果给定年份的3个欺凌变量中的任何一个= 1,则cbully是二进制的并且= 1。 bully_ever是二进制的,如果在某一参与者的任何一项措施中报告了欺凌行为,则为= 1。

我想在我的df中创建一个名为bully_past的新二进制变量。 bully_past表示任何过去年份中cbully = 1的情况。这与bully_ever略有不同。例如,如果参与者被评估了4次:

  • bully_past应使用第4年,第2年和第1年的信息。
  • bully_past应使用第3年第2年和第1年的信息。
  • bully_past应使用第1年第1年的信息。
  • bully_past在第1年应为NA。

我尝试过很多东西,但最近的演绎如下:

fbwb <- fbwb %>%
  dplyr::group_by(id) %>%
  dplyr::mutate(bully_past = case_when(cbully == 1 & year == (year - 1) |
                                         cbully == 1 & year == (year - 2) |
                                         cbully == 1 & year == (year - 3) |
                                         cbully == 1 & year == (year - 4) |
                                         cbully == 1 & year == (year - 5) ~ 1,
                                       (is.na(cbully) & year == (year - 1) &
                                         is.na(cbully) & year == (year - 2) &
                                         is.na(cbully) & year == (year - 3) &
                                         is.na(cbully) & year == (year - 4) &
                                         is.na(cbully) & year == (year - 5)) ~ NA_real_,
                                       TRUE ~ 0)) %>%
  dplyr::ungroup()

这不起作用,因为指示使用年份的语法不正确 - 因此它会生成一列NA值。我做了其他的尝试,但我没能设法考虑所有上一年的观察。

可以使用以下代码在Stata中完成:

gen bullyingever = bullying
sort iid time
replace bullyingever = 1 if bullying[_n - 1]==1 & iid[_n - 1]==iid
replace bullyingever = 1 if bullying[_n - 2]==1 & iid[_n - 2]==iid
replace bullyingever = 1 if bullying[_n - 3]==1 & iid[_n - 3]==iid
replace bullyingever = 1 if bullying[_n - 4]==1 & iid[_n - 4]==iid
replace bullyingever = 1 if bullying[_n - 5]==1 & iid[_n - 5]==iid

我很欣赏有关如何在R中完成此操作的任何输入,最好使用dplyr。

3 个答案:

答案 0 :(得分:5)

在这里,我们可以编写一个帮助函数,可以使用var admin = require('firebase-admin'); var serviceAccount = require("./blahblahblah-firebase-adminsdk-blahblahblah.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://blahblahblah.firebaseio.com" }); admin.auth().setCustomUserClaims("asdfblahblahblahhlkjh", {admin: true}).then(() => { console.log("Custom Claim Added to UID. You can stop this app now."); }); 查看以前的事件(保存事件的累积帐户,让您查看过去)和cumsum,以便专门查看当前价值背后。所以我们有

lag()

然后,您可以将其与had_previous_event <- function(x) { lag(cumsum(!is.na(x) & x==1)>0) }

一起使用
dplyr

返回TRUE / FALSE但如果你想要零/一,你可以将其改为

fbwb %>%
  arrange(id, year) %>% 
  group_by(id) %>%
  mutate(bully_past = had_previous_event(cbully))

答案 1 :(得分:1)

一种解决方案可以使用dplyrifelse作为:

library(dplyr)

  fbwb  %>% group_by(id) %>%
  arrange(id, year) %>%
  mutate(bully_past_year = ifelse(is.na(lag(cbully)), 0L, lag(cbully))) %>%
  mutate(bully_past = ifelse(cumsum(bully_past_year)>0L, 1L, 0 )) %>%
  select(-bully_past_year) %>% as.data.frame()

  #    id   year bully1 bully2 bully3 cbully bully_ever bully_past
  # 1  100    1     NA      1     NA      1          1          0
  # 2  100    2      1      1     NA      1          1          1
  # 3  100    3     NA      0     NA      0          1          1
  # 4  101    1     NA     NA      1      1          1          0
  # 5  102    1     NA      1     NA      1          1          0
  # 6  102    2     NA     NA     NA     NA          1          1
  # 7  102    3     NA      1      1      1          1          1
  # 8  102    4      0      0      0      0          1          1
  # 9  103    1     NA      1     NA      1          1          0
  # 10 103    2     NA      0      0      0          1          1  

答案 2 :(得分:1)

有一种替代方法,在非等自连接中聚合。这种方法的好处是即使使用无序数据也能正常工作。

library(data.table)
# coerce to data.table
bp <- setDT(fbwb)[
  # non equi self-join and aggregate within the join
  fbwb, on = .(id, year < year), as.integer(any(cbully)), by = .EACHI][]
# append new column
fbwb[, bully_past := bp$V1][]
     id year bully1 bully2 bully3 cbully bully_ever bully_past
 1: 100    1     NA      1     NA      1          1         NA
 2: 100    2      1      1     NA      1          1          1
 3: 100    3     NA      0     NA      0          1          1
 4: 101    1     NA     NA      1      1          1         NA
 5: 102    1     NA      1     NA      1          1         NA
 6: 102    2     NA     NA     NA     NA          1          1
 7: 102    3     NA      1      1      1          1          1
 8: 102    4      0      0      0      0          1          1
 9: 103    1     NA      1     NA      1          1         NA
10: 103    2     NA      0      0      0          1          1

非等连接条件仅考虑前几年。因此,根据OP的要求,每个id的第一年是NA

any()函数返回TRUE,如果其中至少有一个值为TRUE(在coersion之后输入逻辑)。在R中,整数值1L对应于逻辑值TRUE