Home > front end >  Using previous value in a row to fill in subsequent values in same column in R (no loops)
Using previous value in a row to fill in subsequent values in same column in R (no loops)

Time:09-30

I have a partially filled in table, there are NAs at the top and bottom of the table (column X in the table below). I want to fill in the table using a rate (0.3) to get the results in the Goal column. This is similar to the fill up/down function in Excel used to copy a formula and fill cells.

df <- data.frame(X = matrix(nrow = 10, ncol = 1, NA))   
df [3:5,1] <- 2:4

   X   Goal
1  NA  1.4
2  NA  1.7
3  2   2
4  3   3
5  4   4
6  NA  4.3
7  NA  4.6
8  NA  4.9
9  NA  5.2
10 NA  5.9

Essentially what I want the code to do is this:

1.4 (X2 answer - 0.3)   
1.7 (2 - 0.3)  
2  
3  
4  
4.3 (4   0.3)  
4.6 (X6 answer   0.3)  
4.9 (X7 answer   0.3)   
5.2 (X8 answer   0.3)   
5.5 (X9 answer   0.3)

I know this can probably be done using loops, but I find them intimidating given my skill level, so I'm looking for a solution that avoids them (if that's even possible).

Thanks in advance

CodePudding user response:

Avoiding loops with nafill() and fcoalesce() from data.table.

library(data.table)
loc = range(which(!is.na(df$X)))
df$Goal =
  fcoalesce(nafill(df$X, "locf"), nafill(df$X, "nocb"))  
  c( -((loc[1] - 1):1)*0.3, rep(0, diff(loc) 1), (1:(nrow(df) - loc[2]))*0.3 )

Still, it is (arguably) much easier to keep track of what is happening in each case with a loop:

# Preallocate
df$Goal = 0

for (i in 1:nrow(df)) {
  if      (i < loc[1]) df$Goal[i] = df$X[loc[1]] - (loc[1] - i) * 0.3
  else if (i > loc[2]) df$Goal[i] = df$X[loc[2]]   (i - loc[2]) * 0.3
  else                 df$Goal[i] = df$X[i     ]
}
#     X Goal
# 1  NA  1.4
# 2  NA  1.7
# 3   2  2.0
# 4   3  3.0
# 5   4  4.0
# 6  NA  4.3
# 7  NA  4.6
# 8  NA  4.9
# 9  NA  5.2
# 10 NA  5.5

  • Related