当满足来自另一列的条件时,计算列中特定行的平均值

时间:2014-04-08 16:06:31

标签: r

基本上,我需要在特定条件下计算行数值的方法。

Name = c("A", "A", "A", "A", "B", "B", "B", "B")
temp = c(22, 22, 26, 23, 18, 20, 18, 17)
peak = c(0, 0, 1, 0, 0, 1, 0, 0)
new = NA
d<- data.frame(Name, temp, peak, new)

当峰值= 1时,计算temp i-1和i + 1的平均值,将该值放在“new”列中。否则,new中的值应与temp相同。我想只在“名称”组中执行此操作,以便组A的临时值不与组B混合。

然后,输出将如下所示:

  Name temp peak  new
1    A   22    0 22.0
2    A   22    0 22.0
3    A   26    1 22.5
4    A   23    0 23.0
5    B   18    0 18.0
6    B   20    1 18.0
7    B   18    0 18.0
8    B   17    0 17.0

我开始写一个ifelse语句,可能看起来像这样:

d$new<-ifelse(d$peak==1, mean(peak[i-1, i+1]), d$temp)  

我也考虑过lapply,但我认为这需要一个循环。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

这应该可以解决问题。没有循环

Name = c("A", "A", "A", "A", "B", "B", "B", "B")
temp = c(22, 22, 26, 23, 18, 20, 18, 17)
peak = c(0, 0, 1, 0, 0, 1, 0, 0)
d<- data.frame(Name, temp, peak)

d$new      = temp
ind        = which(d$peak==1)
d$new[ind] = (d$temp[ind-1]+d$temp[ind+1])/2

答案 1 :(得分:0)

从动物园套餐中试用rollapply

library(zoo)

rollfun <- function(i) with(d[i, ], if (peak[2]) mean(temp[-2]) else temp[2])
transform(d, temp.new = rollapply(seq(0, nrow(d)+1), 3, rollfun))

请注意,这假设边界没有峰值(问题中就是这种情况)。

已修订一些简化。

这是输出:

> Name = c("A", "A", "A", "A", "B", "B", "B", "B")
> temp = c(22, 22, 26, 23, 18, 20, 18, 17)
> peak = c(0, 0, 1, 0, 0, 1, 0, 0)
> new = NA
> d<- data.frame(Name, temp, peak, new)
> library(zoo)
> 
> rollfun <- function(i) with(d[i, ], if (peak[2]) mean(temp[-2]) else temp[2])
> transform(d, temp.new = rollapply(seq(0, nrow(d)+1), 3, rollfun))
  Name temp peak new temp.new
1    A   22    0  NA     22.0
2    A   22    0  NA     22.0
3    A   26    1  NA     22.5
4    A   23    0  NA     23.0
5    B   18    0  NA     18.0
6    B   20    1  NA     18.0
7    B   18    0  NA     18.0
8    B   17    0  NA     17.0