我有一个数据帧,我想在每次出现"Day_1"之前,将列阶段的值替换为7行的"之前".类似地,在同一列中,我想在月经最后一天(Day_, as the number of days for each menstrual cycle changes). Within this data set I need to group by SID and not overwrite any values already present in the column PHASE (Day_1-Day_)之后的7行中填写"After".

        dput(head(data, n = 35))
structure(list(UID = c("UAB001_W1D1", "UAB001_W1D2", "UAB001_W1D3", 
"UAB001_W1D4", "UAB001_W1D5", "UAB001_W1D6", "UAB001_W1D7", "UAB001_W2D1", 
"UAB001_W2D2", "UAB001_W2D3", "UAB001_W2D4", "UAB001_W2D5", "UAB001_W2D6", 
"UAB001_W2D7", "UAB001_W3D1", "UAB001_W3D2", "UAB001_W3D3", "UAB001_W3D4", 
"UAB001_W3D5", "UAB001_W3D6", "UAB001_W3D7", "UAB001_W4D1", "UAB001_W4D2", 
"UAB001_W4D3", "UAB001_W4D4", "UAB001_W4D5", "UAB001_W4D6", "UAB001_W4D7", 
"UAB001_W5D1", "UAB001_W5D2", "UAB001_W5D3", "UAB001_W5D4", "UAB001_W5D5", 
"UAB001_W5D6", "UAB001_W5D7"), SID = c("UAB001", "UAB001", "UAB001", 
"UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", 
"UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", 
"UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", 
"UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", "UAB001", 
"UAB001", "UAB001", "UAB001", "UAB001"), SERIAL = c(" 1", " 2", 
" 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", "11", "12", "13", 
"14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", 
"25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35"
), WEEK = c(" 1", " 1", " 1", " 1", " 1", " 1", " 1", " 2", " 2", 
" 2", " 2", " 2", " 2", " 2", " 3", " 3", " 3", " 3", " 3", " 3", 
" 3", " 4", " 4", " 4", " 4", " 4", " 4", " 4", " 5", " 5", " 5", 
" 5", " 5", " 5", " 5"), DAY = c("1", "2", "3", "4", "5", "6", 
"7", "1", "2", "3", "4", "5", "6", "7", "1", "2", "3", "4", "5", 
"6", "7", "1", "2", "3", "4", "5", "6", "7", "1", "2", "3", "4", 
"5", "6", "7"), NUGENT_SCORE = c(" 0", " 0", " 1", " 3", " 3", 
" 3", " 0", " 0", " 0", " 3", " 1", " 2", " 2", " 3", " 0", " 1", 
" 1", " 2", " 1", " 0", " 5", " 2", " 5", " 7", " 7", " 6", " 6", 
" 7", " 5", " 5", " 7", " 4", " 5", " 3", " 3"), NUGENT_CLASS = c("NO_BV", 
"NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", 
"NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", 
"NO_BV", "NO_BV", "NO_BV", "NO_BV", "NO_BV", "INTER_BV", "NO_BV", 
"INTER_BV", "BV", "BV", "INTER_BV", "INTER_BV", "BV", "INTER_BV", 
"INTER_BV", "BV", "INTER_BV", "INTER_BV", "NO_BV", "NO_BV"), 
    CST = c("I", "I", "I", "I", "I", "I", "I", "I", "I", "I", 
    "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "III", 
    "I", "IV-C", "III", "IV-B", "III", "III", "IV-B", NA, "I", 
    NA, "IV-C", "I", "IV-C", "IV-C"), PH = c("4.4", "4.0", "4.0", 
    "4.4", "4.4", "4.7", "4.4", "4.0", "4.0", "4.4", "4.0", "4.0", 
    "4.0", "4.4", "4.4", "5.3", "5.3", "5.3", "5.0", "4.7", "5.3", 
    "4.4", "4.0", "4.4", "4.7", "4.7", "4.7", "4.4", "5.8", "5.5", 
    "4.7", "4.7", "4.7", "4.7", "4.7"), MENSTRUATION = c("0", 
    "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", 
    "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", 
    "0", "0", "0", "2", "1", "1", "1", "0", "0", "0"), TAMPON = c(" 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0"), PAD = c(" 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 1", " 1", " 1", " 1", " 0", " 0", 
    " 0"), Hygiene_Product = c("None", "None", "None", "None", 
    "None", "None", "None", "None", "None", "None", "None", "None", 
    "None", "None", "None", "None", "None", "None", "None", "None", 
    "None", "None", "None", "None", "None", "None", "None", "None", 
    "Pad", "Pad", "Pad", "Pad", "None", "None", "None"), MENSES = c("NO", 
    "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", 
    "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", "NO", 
    "NO", "NO", "NO", "NO", "NO", "NO", "NO", "YES", "YES", "YES", 
    "YES", "NO", "NO", "NO"), MEN.DAY = c(0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 1, 2, 3, 4, 0, 0, 0), MEN.CYCLE.DAY = c(1L, 2L, 3L, 
    4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 
    17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 
    1L, 2L, 3L, 4L, 5L, 6L, 7L), PHASE = c(NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, "Day_1", "Day_2", "Day_3", 
    "Day_4", NA, NA, NA)), row.names = c(NA, -35L), class = c("tbl_df", 
"tbl", "data.frame"))

我try 了以下方法,但在不同的SID之间以及在SID内,都用"之前"替换了一些日子.

datat$PHASE[pmin(nrow(data), unique(unlist(lapply(which(data$PHASE == "Day_1"), `-`, 1:7))))] <- "Before"

我还try 将上面的代码放到for循环中, for each SID创建新的数据帧,然后我可以将这些数据帧组合在一起,因为我已经有了一个SID(患者)列表,但它不适用于第一天在前6行或最后一天在数据帧结束后不到6天的SID.

for (i in patients) {
  tryCatch({
    data.filt <- data %>% 
                          filter(SID == i) 
    data.filt$PHASE[pmin(nrow(data.filt), unique(unlist(lapply(which(data.filt$PHASE == "Day_1"), `-`, 1:7))))] <- "Before"
    assign(paste0(i), data.filt)
  }, error = function(e){cat(paste0(i, "_ERROR :", conditionMessage(e), "\n"))})
}

如果有人能帮我准确地填写这些数据,我将不胜感激!

*本的回答完美无瑕:

data <- data %>%
                group_by(SID) %>%
                mutate(Start = if_else(is.na(lag(PHASE)) & grepl("Day_", PHASE), row_number(), NA),
                       End = if_else(is.na(lead(PHASE)) & grepl("Day_", PHASE), row_number(), NA)) %>%
                fill(Start, .direction = "up") %>%
                fill(End, .direction = "down") %>%
                mutate(PHASE = if_else(is.na(PHASE) & (Start - row_number() <= 7), "Before", PHASE)) %>%
                mutate(PHASE = if_else(is.na(PHASE) & (row_number() - End <= 7), "After", PHASE)) 

推荐答案

一种方法是在两列中跟踪每个阶段的开始和结束(可以存储为row_number()),或者您可以使用单独的计数器(如数据中的Serial,如果它是数字).您可以通过判断前面或后面的行是否丢失(在阶段之前或之后)来检测阶段开始/结束的时间.然后,您可以根据数据集中最近的阶段,对其他行使用fill以使其可供引用.当当前行位置与开始/结束值之间的差值为<;=7时,添加"之前"和"之后"的标签.所有这些都将按SID分组完成.

library(tidyverse)

datat |>
  group_by(SID) |>
  mutate(Start = if_else(is.na(lag(PHASE)) & grepl("Day_", PHASE), row_number(), NA),
         End = if_else(is.na(lead(PHASE)) & grepl("Day_", PHASE), row_number(), NA)) |>
  fill(Start, .direction = "up") |>
  fill(End, .direction = "down") |>
  mutate(PHASE = if_else(is.na(PHASE) & (Start - row_number() <= 7), "Before", PHASE)) |>
  mutate(PHASE = if_else(is.na(PHASE) & (row_number() - End <= 7), "After", PHASE)) 

R相关问答推荐

通过绘图 Select 线串几何体并为其着色

使用Shiny组合和显示复制和粘贴的数据

R箱形图gplot 2 4组但6个参数

多重RHS固定估计

过滤器数据.基于两列的帧行和R中的外部向量

RStudio中相关数据的分组箱形图

如何在格子中添加双曲曲线

R根据条件进行累积更改

为什么舍入POSIXct会更改能力以匹配等效的POSIXct?

为什么我的基准测试会随着样本量的增加而出现一些波动?

即使硬币没有被抛出,也要保持对其的跟踪

在R中按行按列范围查找最大值的名称

为左表中的所有行使用值Fill滚动左连接

汇总数据的Sheffe检验的P值(平均值和标准差)

使用来自嵌套列和非嵌套列的输入的PURRR:MAP和dplyr::Mariate

具有自定义仓位限制和计数的GGPLATE直方图

如何创建一个由一个连续变量和一个因素变量组成的复杂方框图?

如何在不使用SHINY的情况下将下拉滤镜列表添加到ggploy?

删除r中每个因素级别的最后2行

如何在GGPlot中控制多个图例和线型