如何使用dplyr函数平均R中的相邻列(非重叠)?

时间:2017-12-12 17:58:41

标签: r dplyr time-series average

这是我的数据集的示例。 库(tidyr) 库(dplyr) 资源< - c(“好”,“好”,“坏”,“坏”,“好”,“好”,“坏”,“坏”,“好”,“好”,“坏”, “坏”,“好”,“好”,“坏”,“坏”) 肥料< - c(“无”,“氮”,“无”,“氮”,“无”,“氮”,“无”,“氮”,“无”,“氮”,“无”, “氮”,“无”,“氮”,“无”,“氮”) t1< - 样本(1:20,16) t2< - 样本(1:20,16) t3< - 样本(1:20,16) t4< - 样本(1:20,16) t5< - 样本(1:20,16) t6< - 样本(10:100,16) t7< - 样本(10:100,16) t8< - 样本(10:100,16) t9< - 样本(10:100,16) t10< - 样本(10:100,16) 重复< - c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) 数据< - data.frame(资源,肥料,重复,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) data $ resource< - as.factor(data $ resource) data $ fertilizer< - as.factor(data $ fertilizer) 其中t0,t1,t2..etc是时间点。我需要平均相邻的时间点(非重叠)。 (t1,t2),(t3,t4)..并且新列标题需要具有时间的平均值,以便列读取为t1.5,t3.5,...等。 因此最后我需要只有5列读取t1.5,t3.5,t5.5,t7.5,t9.5 无论如何,这可以使用dplyr函数或R中的任何其他函数来实现吗?

3 个答案:

答案 0 :(得分:1)

为OP修改过的请求编辑:

如果您将所有内容放在一个整齐的格式中,您可以利用滞后/超前函数来平均相邻的行。

library(stringr)
library(forcats)

data %>% 
  gather(key = time, value = value, -replicates, -resource, -fertilizer) %>% 
  mutate(index = as.integer(str_extract(time, "[0-9]+"))) %>% 
  arrange(replicates, index) %>% 
  group_by(resource, fertilizer, replicates) %>% 
  mutate(mid_value = (value + lead(value))/2,
         mid_index = (index + lead(index))/2,
         mid_time = str_c("t",mid_index)) %>% 
  ungroup %>% 
  filter(!is.na(mid_value), index %% 2 == 1) %>% 
  select(replicates, resource, fertilizer, matches("mid")) %>% 
  rename(value = mid_value, time = mid_time, index = mid_index) %>%
  arrange(index) %>% 
  mutate(time = as_factor(time)) %>% 
  select(-index) %>% 
  spread(key = time, value = value) %>% 
  arrange(replicates)

答案 1 :(得分:1)

仅使用基础R的解决方案:您需要以某种方式找到要计算平均值的列。您可以通过搜索t + "somenumber"模式的列名来执行此操作。之后,创建一系列序列,对应于您想要计算平均值的df列号。

relevant_cols <- grep("[0-9]{1,2}", names(df))
start <- min(relevant_cols)
end   <- max(relevant_cols)
cols  <- split(start:end, rep(1:5, each=2))  

如果您查看cols,您会看到它是五个列表,每个元素类似于您想要平均的列组合。这有点像sapply()的用例:

newdf <- sapply(cols, function(x) rowMeans(df[x]) )
colnames(newdf) <- paste0("t", seq(1, diff(range(relevant_cols)), 2) + 0.5)

编辑:我似乎误解了你想要维护什么,不知道什么。您可以只cbind()(部分)旧dfnewdf

cbind(df, newdf)
cbind(df[, -relevant_cols], newdf)   # This is what you want. I think..

答案 2 :(得分:0)

这里你去:

transmute(data, 
          t1.5 = (t1 + t2) / 2,
          t3.5 = (t3 + t4) / 2,
          t5.5 = (t5 + t6) / 2,
          t7.5 = (t7 + t8) / 2,
          t9.5 = (t9 + t10) / 2)