根据上一行/后一行更改列中的值

时间:2012-11-27 23:18:14

标签: r dataframe

想象一下,我有一张表,如:

        ScaleDown ScaleUp
1           0        0
2           1        0
3           0        0
4           0        1
5           0        0

我想要做的是对列执行向上或向下扩展功能,以便更改值以反映刚刚发生的正向条目(缩小)或正向条目(向上扩展)。 所以表格应该看起来像这样:

        ScaleDown ScaleUp
1           0        0
2           1       0.33
3          0.66     0.66
4          0.33      1
5           0        0

任何帮助都非常感激。

1 个答案:

答案 0 :(得分:0)

# Sample Data
df <- data.frame(scaleDown=c(0,1,0,0,0,0,1,0,0,0,1), scaleUp=c(0,1,0,0,0,0,0,1,0,1,0))

# Function call with mapply
mapply(adjust, df, c(F, T), MoreArgs=list(rate=3, rounding=2))

#           scaleDown scaleUp
#      [1,]      0.00    0.67
#      [2,]      1.00    1.00
#      [3,]      0.67    0.00
#      [4,]      0.34    0.00
#      [5,]      0.00    0.00
#      [6,]      0.00    0.34
#      [7,]      1.00    0.67
#      [8,]      0.67    1.00
#      [9,]      0.34    0.50    <{~~ 
#     [10,]      0.00    1.00
#     [11,]      1.00    0.00

功能:

adjust <- function(vec, reverse=FALSE, rate=3, rounding=3) {

  if (reverse)
    vec <- rev(vec)

  # add a dummy "1" to end of vec for calculating ends. Will be removed
  vec <- c(vec, 1)


  len <- length(vec)
  indx <- which(vec[-len] != 0)
  ends <- c(indx[-1L], (length(vec) + rate))

  ranges <- sapply(ends-indx, min, rate)
  subtr <- round(vec[indx]  /  ranges, rounding)

  for(i in 1:length(subtr)) {
    for (j in (ranges[i]-1):1) {
      vec[indx[i] + ranges[i]-j] <- vec[indx[i] + ranges[i]-j-1] - subtr[i]
    }
  }

  # remove dummy element
  vec <- vec[seq(len-1)]

  if (reverse)
    return(rev(vec))
  return(vec)
}