I'm a newby in R with some background in more procedural languages. Currently I'm trying to get away from unnecessary "for" loops and make them using something from the apply family. So here's my problem:
data <- c(0.0008, 0.0007, 0.0040, 0.0081, 0.0217, 0.0292, 0.0332, 0.0451, 0.0533, 0.0621)data <- lapply(data, function(i) ifelse(data[i+1]<data[i], data[i+1]<-(data[i]+data[i+2])/2, data[i+1]))logical(0)I can't figure out where my mistake is - what am I missing here?
lapply is for iterating over multiple objects in a list and returns a list. Read ?lapply. With just a single vector, you won't need/want it.
Here's one non-loop way to go about it:
w = which( c(FALSE, tail(data, -1) < head(data, -1) ) )
data[w] = (data[w-1] + data[w+1])/2
If you have consecutive decreasing elements, your procedure will give weird results. Try with data = c(2, 1, 0, 3) for example, and note that the result is still not monotone. So, I think you probably should not try to vectorize in this way and really ought to be using a loop. Also, you'll need to consider what to do when there is a drop in the final element, like c(2,3,0).
I think this will work, assuming I understand your problem correctly.
data <- c(0.0007, 0.0006, 0.0030, 0.0072, 0.0129, 0.0195, 0.0268, 0.0346, 0.0426, 0.0507)
d1 <- head(data, -1) # get the first 9 elements
d2 <- tail(data, -1) # get the last 9 elements
means <- rowMeans(cbind(d1, d2)) # get the mean of all data[i] & data[i+1] pairs
ifelse(d2 < d1, means, d2)
# [1] 0.00065 0.00300 0.00720 0.01290 0.01950 0.02680 0.03460
# [8] 0.04260 0.05070
# realized we might need to append back the first element of our original data. If so:
data <- c(data[1], ifelse(d2 < d1, means, d2))
data
# [1] 0.00070 0.00065 0.00300 0.00720 0.01290 0.01950 0.02680
# [8] 0.03460 0.04260 0.05070
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With