I am trying to do several analyses on datasets that are in a list in R. I have to generate information about each data set in a list, and then based on that new information, generate another set of information. What I've been finding is that when I conduct these calculations, the "data" is clustering within itself repeatedly, and this gets worse as I do more and more calculations. How can I prevent this kind of clustering? I have provided an example below of this phenomenon, but want to note that this analysis, in terms of is.numeric() and is.character(), is not similar to what I am doing.
lat_1 <- c(23.2, 14.5, 28.6)
lon_1 <- c(12.1, 8.5, 2.2)
lat_2 <- c(89.3, 94.4, 72.3)
lon_2 <- c(45.2, 47, 48.5)
coords_1 <- data.frame(lon_1, lat_1)
coords_2 <- data.frame(lon_2, lat_2)
list_coords <- list(coords_1, coords_2)
list_coords_2 <- lapply(list_coords, function(m) {
list(data = m, numeric_answer = is.numeric(m) )
})
And this is the structure I like, where the original data (data) and the newly created "numeric_answer" are on the same level:
str(list_coords_2)
#Output:
$ :List of 2
..$ data :'data.frame': 3 obs. of 2 variables:
.. ..$ lon_1: num [1:3] 12.1 8.5 2.2
.. ..$ lat_1: num [1:3] 23.2 14.5 28.6
..$ numeric_answer: logi FALSE
However, when I try to add another object to this list, the new data, "another_part", is on a different level than "numeric answer":
list_coords_3 <- lapply(list_coords_2, function(m) {
list(data = m, another_part = is.character(m))
})
str(list_coords_3)
#Output:
List of 2
$ :List of 2
..$ data :List of 2
.. ..$ data :'data.frame': 3 obs. of 2 variables:
.. .. ..$ lon_1: num [1:3] 12.1 8.5 2.2
.. .. ..$ lat_1: num [1:3] 23.2 14.5 28.6
.. ..$ numeric_answer: logi FALSE
..$ another_part: logi FALSE
$ :List of 2
..$ data :List of 2
.. ..$ data :'data.frame': 3 obs. of 2 variables:
.. .. ..$ lon_2: num [1:3] 45.2 47 48.5
.. .. ..$ lat_2: num [1:3] 89.3 94.4 72.3
.. ..$ numeric_answer: logi FALSE
..$ another_part: logi FALSE
It is necessary that it rather all comes out like this:
$ :List of 2
..$ data :'data.frame': 3 obs. of 2 variables:
.. ..$ lon_1: num [1:3] 12.1 8.5 2.2
.. ..$ lat_1: num [1:3] 23.2 14.5 28.6
..$ numeric_answer: logi FALSE
..$ another_part: logi FALSE
CodePudding user response:
I would do this to add another_part
to your list.
You don't need to wrap m
in a list()
. Since m
is already the list element, you are nesting another list inside of it. Instead assign directly to m
.
list_coords_3 <- lapply(list_coords_2, function(m) {
# do your calculation on m then assign the result to another_part
m$another_part = FALSE
return(m)
})
List of 2
$ :List of 3
..$ data :'data.frame': 3 obs. of 2 variables:
.. ..$ lon_1: num [1:3] 12.1 8.5 2.2
.. ..$ lat_1: num [1:3] 23.2 14.5 28.6
..$ numeric_answer: logi FALSE
..$ another_part : logi FALSE
$ :List of 3
..$ data :'data.frame': 3 obs. of 2 variables:
.. ..$ lon_2: num [1:3] 45.2 47 48.5
.. ..$ lat_2: num [1:3] 89.3 94.4 72.3
..$ numeric_answer: logi FALSE
..$ another_part : logi FALSE
CodePudding user response:
you could Map
the original list like:
list_coords |>
Map(f = \(m) list(data = m,
numeric_answer = is.numeric(m),
another_part = is.character(m)
)
)
Map
is a base R function. Package {purrr} offers a variety of convenient helpers for list manipulation.