1. dplyr/tidyr
将“宽”格式转换为“长”格式可能会更好。我们可以dplyr/tidyr
用来获取mean
. 创建一个“ind”列,使用 将数据重塑为“long” 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”中创建额外的列
df[nm1] <- dS
2.基础R
我们可以使用base R
方法而无需更改数据集的格式。从原始数据集 ('df') 中,为数字列名创建索引 ('indx'),删除非数字部分并转换为数字 ('v1')。
indx <- grep('\\d+', names(df))
v1 <- as.numeric(sub('[^0-9]+', '', names(df)[indx]))
循环 'df' ( lapply
)的行match
,使用 'v1' 的 'startyear',使用该索引 ('i1') 获取列unlist
,并计算mean
. 同样可以通过将“endyear”与“v1”匹配来获得索引(“i2”)。基于“i1”和“i2”,计算“within_mean”和“after_mean”。 rbind
列表元素并将输出分配给“df”中的新列(“nm1”)。
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