Looping Through R data to replace all values

Viewed 84

Basic level R programmer trying to re-calibrate data using a weighted effect and some other value. In particular I want to 1) if the weighted effect is negative take the row value of X and subtract the person's value or 2) if the weighted effect is positive take the person's value and subtract X.

Mock data:

p1 <- c(0.4,0.7,0.3,0.2)
p2 <- c(0.8,0.4,0.5,0.1)
p3 <- c(0.6,0.5,0.4,0.3)
wef <- c(1.5,-1.2,1.8,-1.3)
x <- c(0.5,0.4,0.6,0.2)

print(df)
   p1  p2  p3  wef   x
1 0.4 0.8 0.6  1.5 0.5
2 0.7 0.4 0.5 -1.2 0.4
3 0.3 0.5 0.4  1.8 0.6
4 0.2 0.1 0.3 -1.3 0.2

I attempted this (which did nothing and likely would be inefficient with for loops):

for(row in 1:nrow(df)) {
  for(col in 1:ncol(df)) {
    ifelse(weightef[row] < 0, df[row,col]==(df$x[row]-df[row,col]),
           df[row,col]==df[row,col]-df$x[row])
  }
}

my desired output in case the above was to hard to follow is this

 person1 person2 person3 weightef x
1    -0.1     0.3     0.1      1.5   0.5
2    -0.3     0.0    -0.1     -1.2   0.4
3    -0.3    -0.1    -0.2      1.8   0.6
4     0.0     0.1    -0.1     -1.3   0.2
3 Answers

We can do this without a loop in R

nm1 <- grep("^p\\d+", names(df), value = TRUE)
i1 <- df$wef > 0 
df[i1, nm1] <- df[i1, nm1]  - df$x[i1]
df[!i1, nm1] <- df$x - df[!i1, nm1] 

data

df <- data.frame(p1, p2, p3, wef, x)

If you want to use for loops you can do it in this way

#Create dataframe
df = data.frame(p1, p2, p3, wef, x)

#looping lenght of vector wef
for (w in 1:length(df$wef))
{
  #Checking positive or negative weight
  if (df$wef[w] >= 0)
  {
    #subtracting
    df$p1[w] = df$p1[w] - df$x[w]
    df$p2[w] =  df$p2[w] - df$x[w]
    df$p3[w] =  df$p3[w] - df$x[w]
  }
  else
  {
    #subtracting
    df$p1[w] = df$x[w] - df$p1[w]
    df$p2[w] = df$x[w] -  df$p2[w]
    df$p3[w] = df$x[w] -  df$p3[w]
  }
}

#print result
print(df)
    p1   p2   p3  wef   x
1 -0.1  0.3  0.1  1.5 0.5
2 -0.3  0.0 -0.1 -1.2 0.4
3 -0.3 -0.1 -0.2  1.8 0.6
4  0.0  0.1 -0.1 -1.3 0.2

You can using apply and ifelse function in R. This is just one line function, and you are not required to understand grep. The second line of code just put everything into data frame.

result <- apply(df[, 1:3], 2, FUN = function(y) with(df, ifelse(wef < 0, x - y, y - x)))
df <- as.data.frame(cbind(result, wef, x))

    p1   p2   p3  wef   x
1 -0.1  0.3  0.1  1.5 0.5
2 -0.3  0.0 -0.1 -1.2 0.4
3 -0.3 -0.1 -0.2  1.8 0.6
4  0.0  0.1 -0.1 -1.3 0.2
Related