Мы можем сделать это с tidyverse
. После группировки по 'Страна', transmute_at
для создания столбцов 'demean' путем вычитания значений столбцов 'Ex' из их mean
, а затем связывания данных с исходными данными (bind_rows
), arrange
путем 'Country', 'year', replace
NA в 'year', 'Y' для каждой 'Country' с элементами не-NA из этих столбцов
library(tidyverse)
df1 %>%
group_by(Country) %>%
transmute_at(vars(starts_with("Ex")),
list(demean = ~ . - mean(.))) %>%
bind_rows(df1, .) %>%
arrange(Country, year ) %>%
group_by(Country) %>%
mutate_at(vars(year, Y), list(~ replace(., is.na(.), .[!is.na(.)])))
# A tibble: 8 x 7
# Groups: Country [2]
# Country year Y Ex1 Ex2 Ex1_demean Ex2_demean
# <chr> <int> <chr> <int> <int> <dbl> <dbl>
#1 A 2015 lala 5 5 NA NA
#2 A 2016 Popo 2 2 NA NA
#3 A 2015 lala NA NA 1.5 1.5
#4 A 2016 Popo NA NA -1.5 -1.5
#5 B 2015 baba 15 60 NA NA
#6 B 2016 nono 9 20 NA NA
#7 B 2015 baba NA NA 3 20
#8 B 2016 nono NA NA -3 -20
Или в слегка измененном виде
df1 %>%
group_by(Country) %>%
nest %>%
mutate(data = map(data, ~
.x %>%
transmute_at(vars(starts_with("Ex")),
list(demean = ~ . - mean(.))) %>%
bind_cols(.x[1:2], .) %>%
bind_rows(.x, .))) %>%
unnest
Данные
df1 <- structure(list(Country = c("A", "A", "B", "B"), year = c(2015L,
2016L, 2015L, 2016L), Y = c("lala", "Popo", "baba", "nono"),
Ex1 = c(5L, 2L, 15L, 9L), Ex2 = c(5L, 2L, 60L, 20L)),
class = "data.frame", row.names = c(NA, -4L))