I found this behaviour odd and wanted more experienced users to share their thoughts and workarounds. On running the code sample below in R:
sampleList <- list() d<- data.frame(x1 = letters[1:10], x2 = 1:10, stringsAsFactors = FALSE) for(i in 1:nrow(d)) { sampleList[[i]] <- d$x1[i] } print(sampleList[[1]]) #[1] "a" print(sampleList[[2]]) #[1] "b" print(sampleList[[3]]) #[1] "c" print(length(sampleList)) #[1] 10 sampleList[[2]] <- NULL print(length(sampleList)) #[1] 9 print(sampleList[[2]]) #[1] "c" print(sampleList[[3]]) #[1] "d" The list elements get shifted up. Maybe this is as expected, but I am trying to implement a function where I merge two elements of a list and drop one. I basically want to lose that list index or have it as NULL.
Is there any way I can assign NULL to it and not see the above behaviour?
Thank you for your suggestions.
Check out the R-FAQ: In R, if x is a list, then x[i] <- NULL and x[[i]] <- NULL remove the specified elements from x. The first of these is incompatible with S, where it is a no-op. (Note that you can set elements to NULL using x[i] <- list(NULL).)
To convert any R Object to NULL, assign the NULL value to that Object or use the as. null() function and pass the Object to that function, and it will return NULL.
Basic R Syntax: null indicates whether a data object is of the data type NULL (i.e. a missing value). The function returns TRUE in case of a NULL object and FALSE in case that the data object is not NULL. The code above illustrates how to use is. null in R.
In simple words, NULL represents the null or an empty object in R. NA represents a missing value in R. NA can be updated in R by vectors, list and other R objects whereas NULL cannot be coerced.
Good question.
Check out the R-FAQ:
In R, if x is a list, then x[i] <- NULL and x[[i]] <- NULL remove the specified elements from x. The first of these is incompatible with S, where it is a no-op. (Note that you can set elements to NULL using x[i] <- list(NULL).)
consider the following example:
> t <- list(1,2,3,4) > t[[3]] <- NULL # removing 3'd element (with following shifting) > t[2] <- list(NULL) # setting 2'd element to NULL. > t [[1]] [2] 1 [[2]] NULL [[3]] [3] 4 UPDATE:
As the author of the R Inferno commented, there can be more subtle situations when dealing with NULL. Consider pretty general structure of code:
# x is some list(), now we want to process it. > for (i in 1:n) x[[i]] <- some_function(...) Now be aware, that if some_function() returns NULL, you maybe will not get what you want: some elements will just disappear. you should rather use lapply function. Take a look at this toy example:
> initial <- list(1,2,3,4) > processed_by_for <- list(0,0,0,0) > processed_by_lapply <- list(0,0,0,0) > toy_function <- function(x) {if (x%%2==0) return(x) else return(NULL)} > for (i in 1:4) processed_by_for[[i]] <- toy_function(initial[[i]]) > processed_by_lapply <- lapply(initial, toy_function) > processed_by_for [[1]] [1] 0 [[2]] [1] 2 [[3]] NULL [[4]] [1] 4 > processed_by_lapply [[1]] NULL [[2]] [1] 2 [[3]] NULL [[4]] [1] 4
Your question is a bit confusing to me.
Assigning null to an existing object esentially deletes that object (this can be very handy for instance if you have a data frame and wish to delete specific columns). That's what you've done. I am unable to determine what it is that you want though. You could try
sampleList[[2]] <- NA instead of NULL, but if by "I want to lose" you mean delete it, then you've already succeeded. That's why, "The list elements get shifted up."
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