После группировки по 'group', mutate
столбцы 'col1' до 'col4' со значением min
положительных и отрицательных чисел, затем добавьте сумму чисел с помощью 'col5' и обновите 'col5.Позже, обновите 'col1' до 'col4', вычитая из соответствующих столбцов исходного набора данных ('df1')
library(dplyr)
df2 <- df1 %>%
group_by(group) %>%
mutate_at(3:6,
funs(case_when(. < 0 ~ if(any(. < 0)) as.numeric(min(.[. <0])) else NA_real_,
. > 0 ~ if(any(. > 0)) as.numeric(min(.[. > 0])) else NA_real_,
TRUE ~ as.numeric(.)))) %>%
ungroup %>%
mutate(col5 = col5 + rowSums(.[3:6]))
nm1 <- paste0("col", 1:4)
#nm1 <- 3:6
df2[nm1] <- df1[nm1] - df2[nm1]
df2
# A tibble: 8 x 7
# date group col1 col2 col3 col4 col5
# <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1234 1 3 1 0 2 94
#2 1235 1 0 3 2 0 195
#3 1234 1 0 0 5 0 402
#4 1235 1 4 0 0 6 903
#5 1235 2 0 0 0 94 761
#6 1233 2 0 0 53 0 861
#7 1342 2 18 0 44 0 -37
#8 1234 2 66 13 45 1 46
или используя модификацию с parse_exprs
library(rlang)
expr <- paste(glue::glue('{nm1} - {nm1}_new'), collapse=";")
df1 %>%
group_by(group) %>%
mutate_at(3:6, funs(new = ave(., sign(.), FUN = min))) %>%
ungroup %>%
mutate(col5 = col5 + select(., col1_new:col4_new) %>%
reduce(`+`)) %>%
transmute(date, group, !!! parse_exprs(expr), col5) %>%
rename_at(3:6, ~ nm1)
# A tibble: 8 x 7
# date group col1 col2 col3 col4 col5
# <int> <int> <int> <int> <int> <int> <int>
#1 1234 1 3 1 0 2 94
#2 1235 1 0 3 2 0 195
#3 1234 1 0 0 5 0 402
#4 1235 1 4 0 0 6 903
#5 1235 2 0 0 0 94 761
#6 1233 2 0 0 53 0 861
#7 1342 2 18 0 44 0 -37
#8 1234 2 66 13 45 1 46
Или преобразовать в «длинный» формат для выполнения расчетов, а затем изменить его на «широкий»
library(tidyverse)
df1 %>%
rownames_to_column('rn') %>%
gather(key, val, col1:col4) %>%
group_by(group, key, sn= sign(val)) %>%
mutate(mnVal = min(val)) %>%
group_by(rn) %>%
mutate(col5 = col5 + sum(mnVal), val = val - mnVal) %>%
select(-sn, -mnVal) %>%
spread(key, val) %>%
ungroup %>%
select(names(df1))
data
df1 <- structure(list(date = c(1234L, 1235L, 1234L, 1235L, 1235L, 1233L,
1342L, 1234L), group = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), col1 = c(-2L,
4L, -5L, 8L, -72L, 32L, -54L, 98L), col2 = c(3L, 5L, 2L, 2L,
83L, -21L, 0L, -8L), col3 = c(4L, -2L, 9L, -4L, -54L, -1L, -10L,
-9L), col4 = c(-5L, -7L, 1L, 7L, 98L, 4L, -11L, -10L), col5 = c(100L,
200L, 400L, 900L, 800L, 900L, 100L, 100L)), .Names = c("date",
"group", "col1", "col2", "col3", "col4", "col5"),
class = "data.frame", row.names = c(NA,
-8L))