I currently have a large list with around 5000 elements. A reproducible example is like:
List.5000 <- replicate(5000, c(list(A='A',value.A=10),list(B='B',value.B=20)), simplify = F)
which has:
> List.5000
[[1]]
[[1]]$A
[1] "A"
[[1]]$value.A
[1] 10
[[1]]$B
[1] "B"
[[1]]$value.B
[1] 20
[[2]]
[[2]]$A
[1] "A"
[[2]]$value.A
[1] 10
[[2]]$B
[1] "B"
[[2]]$value.B
[1] 20
....
When I call names(List.5000)
it returns NULL
. But when I call names(List.5000[[1]])
, it gives:
"A" "value.A" "B" "value.B"
I would like to change the name "B"
to "Z"
. Is there a way to do this without resorting to creating a new list, then looping and reconstructing?
for(i in seq_along(List.5000))
names(List.5000[[i]])[names(List.5000[[i]]) == 'B'] <- 'Z'
Or, if you prefer lapply
/map
:
List.5000 <- lapply(List.5000,
function(x) {names(x)[names(x) == 'B'] <- 'Z'; x})
library(purrr)
List.5000 <- map(List.5000, ~{names(.)[names(.) == 'B'] <- 'Z'; .})
If the names really are all the same you could just do
ind <- names(List.5000[[1]]) == 'B'
for(i in seq_along(List.5000))
names(List.5000[[i]])[ind] <- 'Z'
The bracket syntax is a little faster:
x <- List.5000[[1]]
microbenchmark(
sub = names(x) <- sub("^B$", "Z", names(x))
, ifelse = names(x) <- ifelse(names(x) == 'B', 'Z', names(x))
, stringi = names(x) <- str_replace(names(x), "^B$", "Z")
, replace = names(x) <- replace(names(x), names(x) == 'B', 'Z')
, bracket = names(x)[names(x) == 'B'] <- 'Z'
)
# Unit: microseconds
# expr min lq mean median uq max neval
# sub 22.041 31.2265 58.24097 46.9650 78.5075 373.637 100
# ifelse 13.309 22.4110 44.00665 30.2235 65.1395 113.693 100
# stringi 153.880 313.0400 346.41543 358.4795 383.4130 631.354 100
# replace 4.067 6.3205 13.09022 8.1760 11.9280 54.075 100
# bracket 3.246 4.5265 10.38177 5.9180 7.9925 55.278 100
Still a little unsatisfying, as none of these methods modify the list in place.
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