#r #list #null
#r #Список #null
Вопрос:
Я нашел это поведение странным и хотел, чтобы более опытные пользователи поделились своими мыслями и обходными путями. При запуске приведенного ниже примера кода в 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"
Элементы списка сдвигаются вверх.
Возможно, это так, как и ожидалось, но я пытаюсь реализовать функцию, в которой я объединяю два элемента списка и удаляю один. Я в основном хочу потерять этот индекс списка или иметь его как NULL.
Есть ли какой-либо способ присвоить ему NULL и не увидеть вышеупомянутое поведение?
Спасибо за ваши предложения.
Комментарии:
1.
unlist
Помогло бы вашему делу?2. Вы неправильно используете R — попробуйте реализовать больше векторизации, иначе ваши коды останутся медленными, уродливыми и нелогичными.
Ответ №1:
Хороший вопрос.
Ознакомьтесь с R-FAQ:
В R, если x является списком, то x[i] <- NULL и x[[i]] <- NULL удаляют указанные элементы из x. Первый из них несовместим с S, где он не работает. (Обратите внимание, что вы можете присвоить элементам значение NULL, используя x[i] <- list(NULL) .)
рассмотрим следующий пример:
> 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
Обновить:
Как прокомментировал автор R Inferno, при работе с NULL могут возникать более тонкие ситуации. Рассмотрим довольно общую структуру кода:
# x is some list(), now we want to process it.
> for (i in 1:n) x[[i]] <- some_function(...)
Теперь имейте в виду, что если some_function()
returns NULL
, вы, возможно, не получите то, что хотите: некоторые элементы просто исчезнут. вам лучше использовать lapply
function .
Взгляните на этот игрушечный пример:
> 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
Комментарии:
1. Это Circle 8.1.55 из «The R Inferno» burns-stat.com/pages/Tutor/R_inferno.pdf Circle 8.1.56 — это более тонкая версия этого.
2. Спасибо за подробное объяснение. Как читать руководства и не упускать из виду эти тонкости!!!!
Ответ №2:
Ваш вопрос немного сбивает меня с толку.
Присвоение null существующему объекту по существу удаляет этот объект (это может быть очень удобно, например, если у вас есть фрейм данных и вы хотите удалить определенные столбцы). Это то, что вы сделали. Я не могу определить, что именно вы хотите. Вы могли бы попробовать
sampleList[[2]] <- NA
вместо NULL, но если под «я хочу потерять» вы подразумеваете его удаление, то вы уже добились успеха. Вот почему «элементы списка сдвигаются вверх».
Ответ №3:
obj = list(x = "Some Value")
obj = c(obj,list(y=NULL)) #ADDING NEW VALUE
obj['x'] = list(NULL) #SETTING EXISTING VALUE
obj
Ответ №4:
Если вам нужно создать список нулевых значений, которые позже вы можете заполнить значениями (например, фреймами данных), здесь нет претензий:
B <-vector("list", 2)
a <- iris[sample(nrow(iris), 10), ]
b <- iris[sample(nrow(iris), 10), ]
B[[1]]<-a
B[[2]]<-b
Приведенные выше ответы похожи, но я подумал, что это стоит опубликовать.
Ответ №5:
Мне потребовалось некоторое время, чтобы разобраться с этим для списка списков. Мое решение было:
mylist[[i]][j] <- list(double())