I'm trying to dynamically update cells in a data frame with an apply-type function. Here's the reproducible example:
demo.df <- structure(list(node_id = 1:21, depth = c(4, 3, 2, 1, 0, 0,
1, 0, 0, 2, 1, 0, 0, 1, 0, 0, 2, 1, 0, 0, 0), x_position = c(NA, NA,
NA, NA, 1, 2, NA, 3, 4, NA, NA, 5, 6, NA, 7, 8, NA, NA, 9,10, 11), X1
= 1:21, X2 = c(2L, 3L, 4L, 5L, NA, NA, 8L, NA, NA, 11L, 12L, NA, NA,
15L, NA, NA, 18L, 19L, NA, NA, NA), X3 = c(17L, 10L, 7L, 6L, NA, NA,
9L, NA, NA, 14L, 13L, NA, NA, 16L, NA, NA, 21L, 20L, NA, NA, NA)),
class = "data.frame", row.names = c(1L, 2L, 4L, 8L, 16L, 17L, 9L, 18L,
19L, 5L, 10L, 20L, 21L, 11L, 22L, 23L, 3L, 6L, 12L, 13L, 7L))
node_sequence <- c(4,7,11,14,18,3,10,17,2,1)
I want to update x_position based on the mean of the following columns, going through the rows in a specified order, so
x_spot <- function (x)
{mean(demo.df$x_position[which(demo.df$node_id%in%demo.df[x,c(4:6)])],
na.rm = TRUE)
}
This clumsy code gets the right result:
demo.df$x_position[node_sequence[1]] <- x_spot(node_sequence[1])
demo.df$x_position[node_sequence[2]] <- x_spot(node_sequence[2])
demo.df$x_position[node_sequence[3]] <- x_spot(node_sequence[3])
demo.df$x_position[node_sequence[4]] <- x_spot(node_sequence[4])
demo.df$x_position[node_sequence[5]] <- x_spot(node_sequence[5])
demo.df$x_position[node_sequence[6]] <- x_spot(node_sequence[6])
demo.df$x_position[node_sequence[7]] <- x_spot(node_sequence[7])
demo.df$x_position[node_sequence[8]] <- x_spot(node_sequence[8])
demo.df$x_position[node_sequence[9]] <- x_spot(node_sequence[9])
demo.df$x_position[node_sequence[10]] <- x_spot(node_sequence[10])
demo.df$x_position
But I can't figure out how to assign new values within vapply for something elegant like
vapply(1:10, function(x) {demo.df$x_position[node_sequence[x]] <- x_spot(node_sequence[x])}, numeric(1))
What am I missing? Maybe return() somewhere in the code?
As the previous values are used for calculating the next value, an option is <<-
vapply(1:10, function(x) {
demo.df$x_position[node_sequence[x]] <<- x_spot(node_sequence[x])}, numeric(1))
demo.df$x_position
In this case a for
loop is much better
for(i in seq_along(node_sequence)) {
demo.df$x_position[node_sequence[i]] <- x_spot(node_sequence[i])
}