Вот один из вариантов. Сгруппированные по 'ID' и match
ed индекса 'CYCLE' (как показано в ожидаемом выводе), измените значения "DIAM" на NA
, если any
из "DIAM" имеет "NE", то summarise
, взяв sum
из 'DIAM', убедившись, что если все значения NA
, верните NA
library(tidyverse)
dfin %>%
group_by(ID, CYCLE = match(CYCLE, unique(CYCLE))-1) %>%
mutate(DIAM = as.numeric(replace(DIAM, any(DIAM== "NE"), NA))) %>%
summarise(SUM = NA^all(is.na(DIAM)) * sum(DIAM, na.rm = TRUE))
# A tibble: 4 x 3
# Groups: ID [?]
# ID CYCLE SUM
# <int> <dbl> <dbl>
#1 1 0 12
#2 1 1 8
#3 1 2 NA
#4 1 3 6
Или используйте условие if/else
после шага group_by
dfin %>%
group_by(ID, CYCLE = match(CYCLE, unique(CYCLE))-1) %>%
summarise(SUM = if("NE" %in% DIAM) NA else sum(as.numeric(DIAM), na.rm = TRUE))
Или используя ту же логику с data.table
library(data.table)
setDT(dfin)[, .(SUM = if("NE" %in% DIAM) NA_real_ else
sum(as.numeric(DIAM), na.rm = TRUE)), .(ID, CYCLE = rleid(CYCLE)-1)]
# ID CYCLE SUM
#1: 1 0 12
#2: 1 1 8
#3: 1 2 NA
#4: 1 3 6
* * Данные тысяча двадцать-один
dfin <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L),
CYCLE = c("BASELINE",
"BASELINE", "CYCLE 1", "CYCLE 1", "CYCLE 2", "CYCLE 2", "CYCLE 3",
"CYCLE 3"), NUM = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), DIAM = c("8",
"4", "6", "2", "6", "NE", "6", NA)), row.names = c(NA, -8L),
class = "data.frame")