У меня довольно сложная структура данных со списком списков, каждый из которых, в свою очередь, имеет числовые векторы различной длины. Мне нужно заменить некоторые значения в векторах на NA, основываясь на отдельном векторе той же длины, что и основной список. Но вместо того, чтобы заменять только определенные значения, R заменяет весь вектор. Сильфон, пример:
> ## Minimal example with a list of vectors
> # Creating list
> mylist = rep(list(1:3), 3)
>
> # Vector on which I will base the replacement
> myvec = 1:3
>
> # Replacing 1s by NA
> for(i in 1:length(mylist)){
+ mylist[[i]] = sapply(mylist[[i]], function(x) x[x ==myvec[i]] = NA)
+ }
>
> # But I get NAs for every observation
> mylist
[[1]]
[1] NA NA NA
[[2]]
[1] NA NA NA
[[3]]
[1] NA NA NA
>
> # This is what I wanted:
> list(c(NA, 2, 3), c(1, NA, 3), c(1, 2, NA))
[[1]]
[1] NA 2 3
[[2]]
[1] 1 NA 3
[[3]]
[1] 1 2 NA
>
>
> ## More complex example, with a list of lists of vectors that more closely approximates my data structure
> # Creating list of lists
> mynewlist = rep(list(rep(list(1:3), 3)), 3)
>
> # Replacing 1s by NAs
> for(i in 1:length(mynewlist)){
+ mynewlist[[i]] = lapply(mynewlist[[i]], function(x) x[x ==myvec[i]] = NA)
+ }
>
> # But now each vector becomes a single NA
> mynewlist
[[1]]
[[1]][[1]]
[1] NA
[[1]][[2]]
[1] NA
[[1]][[3]]
[1] NA
[[2]]
[[2]][[1]]
[1] NA
[[2]][[2]]
[1] NA
[[2]][[3]]
[1] NA
[[3]]
[[3]][[1]]
[1] NA
[[3]][[2]]
[1] NA
[[3]][[3]]
[1] NA
>
> # What I wanted:
> list(rep(list(c(NA, 2, 3)), 3), rep(list(c(1, NA, 3)), 3), rep(list(c(1, 2, NA)), 3))
[[1]]
[[1]][[1]]
[1] NA 2 3
[[1]][[2]]
[1] NA 2 3
[[1]][[3]]
[1] NA 2 3
[[2]]
[[2]][[1]]
[1] 1 NA 3
[[2]][[2]]
[1] 1 NA 3
[[2]][[3]]
[1] 1 NA 3
[[3]]
[[3]][[1]]
[1] 1 2 NA
[[3]][[2]]
[1] 1 2 NA
[[3]][[3]]
[1] 1 2 NA
Обратите внимание, что то же самое происходит независимо от конкретного значения замещения (если вместо NA я заменяю замену, например, на 0, тогда 0 заменяет все значения, независимо от условия).
Что происходит? Почему lapply / sapply игнорирует условие?
Кстати, я приветствую предложения сделать это без циклов for.
Редактировать: в дополнение к редактированию кода выше, чтобы прояснить, что я основываю замену на отдельном векторе (отсюда цикл for), я смог получить то, что я хочу, с помощью ifelse. Я до сих пор не понимаю, почему l / sapply не распознает выбор и замену в скобках. Буду признателен за любое объяснение этого, а также о том, как сделать это без цикла.
Код с ifelse:
> # Creating list of lists
> mynewestlist = rep(list(rep(list(1:3), 3)), 3)
>
> # Replacing 1s by NAs
> for(i in 1:length(mynewestlist)){
+ mynewestlist[[i]] = lapply(mynewestlist[[i]], function(x) ifelse(x ==myvec[i], NA, x))
+ }
>
> # That's better:
> mynewestlist
[[1]]
[[1]][[1]]
[1] NA 2 3
[[1]][[2]]
[1] NA 2 3
[[1]][[3]]
[1] NA 2 3
[[2]]
[[2]][[1]]
[1] 1 NA 3
[[2]][[2]]
[1] 1 NA 3
[[2]][[3]]
[1] 1 NA 3
[[3]]
[[3]][[1]]
[1] 1 2 NA
[[3]][[2]]
[1] 1 2 NA
[[3]][[3]]
[1] 1 2 NA
> list(rep(list(c(NA, 2, 3), 3), rep(list(1, NA, 3), 3), rep(list(1, 2, NA), 3))