Comportamento de <- NULL em listas versus data.frames para remover dados

Muitos usuários de R eventualmente descobrem muitas maneiras de remover elementos de seus dados. Uma maneira é usarNULL, particularmente quando você quer fazer algo como soltar uma coluna de umdata.frame ou soltar um elemento de umlist.

Eventualmente, um usuário se depara com uma situação em que deseja descartar várias colunas de umdata.frame imediatamente, e eles bateram em cima<- list(NULL) como a solução (desde o uso<- NULL resultará em um erro).

A data.frame é um tipo especial delist, então não seria tão difícil imaginar que as abordagens para remover itens de umlist deve ser o mesmo que remover colunas de umdata.frame. No entanto, eles produzem resultados diferentes, como pode ser visto no exemplo abaixo.

## Make some small data--two data.frames and two lists
cars1 <- cars2 <- head(mtcars)[1:4]
cars3 <- cars4 <- as.list(cars2)

## Demonstration that the `list(NULL)` approach works
cars1[c("mpg", "cyl")] <- list(NULL)
cars1
#                   disp  hp
# Mazda RX4          160 110
# Mazda RX4 Wag      160 110
# Datsun 710         108  93
# Hornet 4 Drive     258 110
# Hornet Sportabout  360 175
# Valiant            225 105

## Demonstration that simply using `NULL` does not work
cars2[c("mpg", "cyl")] <- NULL
# Error in `[<-.data.frame`(`*tmp*`, c("mpg", "cyl"), value = NULL) : 
#   replacement has 0 items, need 12

Mude para aplicar o mesmo conceito a umliste compare a diferença de comportamento.

## Does not fully drop the items, but sets them to `NULL`
cars3[c("mpg", "cyl")] <- list(NULL)
# $mpg
# NULL
# 
# $cyl
# NULL
# 
# $disp
# [1] 160 160 108 258 360 225
# 
# $hp
# [1] 110 110  93 110 175 105

## *Does* drop the `list` items while this would
##   have produced an error with a `data.frame`
cars4[c("mpg", "cyl")] <- NULL
# $disp
# [1] 160 160 108 258 360 225
# 
# $hp
# [1] 110 110  93 110 175 105

As principais questões que tenho são, se umdata.frame é umlist, por que se comporta de maneira tão diferente nesse cenário? Existe uma maneira infalível de saber quando um elemento será descartado, quando ele produzirá um erro, e quando ele simplesmente receberá um erro?NULL valor? Ou dependemos de tentativa e erro para isso?

questionAnswers(1)

yourAnswerToTheQuestion