R语言 如何创建一个具有多个条件的循环来审查个人

6vl6ewon  于 2023-10-13  发布在  其他
关注(0)|答案(1)|浏览(98)

我有以下数据集:

# Create the dataset
set.seed(123)  # for reproducibility
new_dataset <- data.frame(
  ID = sample(1000:9999, 10, replace = TRUE)  # Generate ID
)

# Create variables for each year from 2011 to 2017 and assign random numbers from 0 to 5
for (year in 2011:2017) {
  weeks_in_year <- if (year %% 4 == 0) 53 else 52  # Check for leap year

  # Create a matrix for each year with random numbers
  year_matrix <- matrix(sample(0:5, 10 * weeks_in_year, replace = TRUE), ncol = weeks_in_year)

  # Assign the matrix to a new variable with the appropriate column names
  colnames(year_matrix) <- paste0("y_", substr(year, 3, 4), sprintf("%02d", 1:weeks_in_year))
  new_dataset[paste0("y_", substr(year, 3, 4), sprintf("%02d", 1:weeks_in_year))] <- 
  year_matrix
  }

# Determine the number of cells to set to blank (70% of total cells)
total_cells <- nrow(new_dataset) * ncol(new_dataset)
cells_to_set_blank <- round(0.7 * total_cells)

# Randomly select cells to set to blank
cells_to_modify <- sample(1:total_cells, cells_to_set_blank, replace = FALSE)
rows_to_modify <- (cells_to_modify - 1) %/% ncol(new_dataset) + 1
cols_to_modify <- (cells_to_modify - 1) %% ncol(new_dataset) + 1

# Set selected cells to blank (empty strings) in the new data frame
for (i in 1:length(cells_to_modify)) {
  new_dataset[rows_to_modify[i], cols_to_modify[i] + 1] <- NA  # +1 to account for 'ID' column
}

# Add start_of_follow_up and end_of_follow_up columns
new_dataset$start_of_follow_up <- c(1146, 1247, 1348, 1449, 1150, 1151, 1150, 1150, 1150, 
1150)
new_dataset$end_of_follow_up   <- c(1248, 1249, 1352, 1552, 1252, 1312, 1205, 1305, 1305, 
1207)

现在这个数据是从2011年到2017年的登记数据。
变量ID是指示ID的变量,并且是每行的一个变量
以y_开头的变量是以以下格式表示日期的变量:例如,y_1148表示11是2011年,48表示第48周,y_1207表示12是2012年,07是该年的第07周,依此类推。所以所有这些变量都表明登记册上每周都有一次随访。
这些变量具有从0到5的一些代码,其指示对这些个体进行审查的原因,并且一些是空单元,其意味着这些人没有任何代码。
然后我有另外两个变量,分别命名为start_of_follow_up和end_of_follow_up,它们表示每个个体的跟踪应该从哪一年哪一周开始,以及跟踪应该从哪一年哪一周结束。例如,对于第一个ID,跟踪应该在1146开始,这意味着2011年和第46周,并在1248结束,这意味着2012年和第48周。这个日期应该与以y_开头的变量相匹配,这意味着,例如,对于我想要在这些变量范围内搜索的第一个人:y_1146直到y_1248,如果我进一步写下的任何代码存在,那么所有其他个体都是如此。
所以我想做的是创建一个代码,它在每个单独的代码中搜索,从0到5,在从start_of_follow_up和end_of_follow_up定义的日期范围内,以y_开头的变量。
代码是0或1或2或4或连续两次代码5。如果你发现任何这些代码首先在这些范围内从开始到结束的后续,然后我想审查该观察,并创建一个新的变量命名为censored_week,将有为每个观察变量y_的名称,代码0或1或2或4或两个连续的时间2被发现。所以我知道每个人是哪周被审查的。
例如,第一个个体在变量y_1146中具有代码1。所以在变量censored_week中,我希望你为那个人给予代码1146,这将表明这个人在那一年和那一周被审查。后续工作应该停止。然后我需要另一个变量来说明这个人为什么被审查。这意味着我想要的原因,即。在随访期间首先发现的代码,即,0或1或2或4或连续两次的代码2。
如果我们在每个参与者周的这些范围内找不到任何这些代码,则给予该变量随访期结束时的值,该值将指示参与者未被删失。在另一个变量中写上这个人没有被审查。
希望有人能帮我完成这个艰巨的任务:)
Thanks in advance

waxmsbnn

waxmsbnn1#

我会通过将数据旋转到更长的格式来做到这一点。然后,您可以使用group_by(ID)并识别各种代码何时发生。然后,您可以为每个ID选择最早的代码,然后将其合并回原始数据。

library(tidyr)
library(dplyr)
library(stringr)
censored_codes <- new_dataset %>% 
  pivot_longer(starts_with("y_"), names_to="week", values_to = "code") %>% 
  mutate(week_num = as.numeric(str_extract(week, "\\d+"))) %>% 
  group_by(ID) %>% 
  filter(week_num >= start_of_follow_up & week_num <= end_of_follow_up) %>% 
  mutate(code0 = ifelse(code == 0, week, NA), 
         code1 = ifelse(code == 1, week, NA), 
         code2 = ifelse(code == 2, week, NA), 
         code4 = ifelse(code == 4, week, NA),
         code22 = ifelse(code == 2 & lag(code) == 2, week, NA)) %>%
  select(ID, code0:code22) %>% 
  pivot_longer(-ID, names_to = "censored_code", values_to = "censored_week") %>%
  na.omit() %>% 
  group_by(ID) %>% 
  arrange(censored_week, .by_group = TRUE) %>% 
  slice_head(n=1) 
censored_codes
#> # A tibble: 10 × 3
#> # Groups:   ID [10]
#>       ID censored_code censored_week
#>    <int> <chr>         <chr>        
#>  1  2841 code0         y_1150       
#>  2  3462 code1         y_1146       
#>  3  3510 code0         y_1248       
#>  4  3756 code4         y_1152       
#>  5  3985 code4         y_1452       
#>  6  4370 code1         y_1203       
#>  7  5760 code0         y_1201       
#>  8  6106 code2         y_1150       
#>  9  7745 code0         y_1204       
#> 10  9717 code0         y_1348

new_dataset <- left_join(new_dataset, censored_codes)
#> Joining with `by = join_by(ID)`

如果没有数据和检查输出的东西,我不想说这肯定会在你的情况下工作,但你应该能够做一些像下面这样的事情来计算女性的两个连续值2:

censored_codes2 <- new_dataset %>% 
  pivot_longer(starts_with("y_"), names_to="week", values_to = "code") %>% 
  mutate(week_num = as.numeric(str_extract(week, "\\d+"))) %>% 
  group_by(ID) %>% 
  filter(week_num >= start_of_follow_up & week_num <= end_of_follow_up) %>% 
  mutate(censored_week = ifelse(code == 2 & lag(code) == 2 & gender == 0, week, NA)) %>%
  select(ID, censored_week) %>% 
  arrange(censored_week, .by_group = TRUE) %>% 
  slice_head(n=1)

相关问题