1. dplyr/tidyr
Это может быть лучше, чтобы преобразовать 'широкий' формат в формат 'длинных'. Мы могли бы использовать dplyr/tidyr
, чтобы получить mean
. Создайте столбец «ind», измените данные на «длинный» с помощью gather
, разделите столбец «переменная» на два столбца («var1», «var2») с помощью extract
, группу «ind», получите значения mean
столбец «значение» после того, как Подменю он основан на другой логический индекс, созданный (т.е. var2 < startyear
, var2 >= startyear & var2 <= endyear
и var2 >endyear
)
library(dplyr)
library(tidyr)
dS <- df %>%
mutate(ind=row_number()) %>%
gather(variable, value, starts_with('y')) %>%
extract(variable, c('var1', 'var2'), '([^0-9]+)([0-9]+)',
convert=TRUE) %>%
group_by(ind) %>%
summarise(before_mean= mean(value[var2 < startyear]),
within_mean = mean(value[var2 >= startyear &
var2 <= endyear]),
after_mean=mean(value[var2 >endyear])) %>%
as.data.frame()
nm1 <- paste(c('before', 'within', 'after'), 'mean', sep="_")
dS
# ind before_mean within_mean after_mean
#1 1 629.6667 44.0 65.0
#2 2 636.0000 57.2 1179.4
Мы можем создать дополнительные столбцы в «ДФ» из вышеприведенного вывода
df[nm1] <- dS
2. основание R
Мы можем использовать методы base R
и без изменения формата набора данных. Из исходного набора данных ('df') создайте индекс ('indx') числовых имен столбцов, удалите нечисловую часть и преобразуйте в числовой ('v1').
indx <- grep('\\d+', names(df))
v1 <- as.numeric(sub('[^0-9]+', '', names(df)[indx]))
Петля строки 'ДФ' (lapply
), match
'StartYear' с 'v1', используйте этот индекс ('i1'), чтобы получить столбцы, unlist
и вычислить mean
. То же самое можно сделать, сопоставив «endyear» с «v1», чтобы получить индекс («i2»). Основываясь на 'i1' и 'i2', вычислите 'inside_mean' и 'after_mean'. rbind
элементы списка и назначить вывод новым столбцам ('nm1') в 'df'.
df[nm1] <- do.call(rbind,lapply(1:nrow(df), function(i) {
i1 <- match(df$startyear[i], v1)
before_mean<- mean(unlist(df[i,1:(i1-1),drop=FALSE]))
i2 <- match(df$endyear[i], v1)
within_mean <- mean(unlist(df[i,i2:i1]))
after_mean <- mean(unlist(df[i,match(v1[(i2+1):length(v1)],v1)]))
data.frame(before_mean,within_mean, after_mean) }))
df[nm1]
# before_mean within_mean after_mean
#1 629.6667 44.0 65.0
#2 636.0000 57.2 1179.4