Почему sapply () возвращает список? - PullRequest
14 голосов
/ 12 марта 2012

Я столкнулся со странным поведением в R с функцией sapply(). Предполагается, что эта функция возвращает вектор, но в особом случае, когда вы даете ему пустой вектор, она возвращает список.

Правильное поведение с вектором:

a = c("A", "B", "C")
a[a == "B"]  # Returns "B"
a[sapply(a, function(x) {x == "B"})] # Returns "B"

Правильное поведение со значением NULL:

a = NULL
a[a == "B"]  # Returns NULL
a[sapply(a, function(x) {x == "B"})] # Returns NULL

Странное поведение с пустым вектором:

a = vector()
a[a == "B"]  # Returns NULL
a[sapply(a, function(x) {x == "B"})] # Erreur : type 'list' d'indice incorrect

То же сообщение об ошибке, что и с этим утверждением:

a[list()] # Erreur dans a[list()] : type 'list' d'indice incorrect

Почему? Это ошибка?

Из-за этого странного поведения я использую unlist(lapply()).

Ответы [ 3 ]

18 голосов
/ 12 марта 2012

Настоящая причина этого в том, что sapply не знает, что ваша функция вернет без вызова. В вашем случае функция возвращает logical, но, поскольку sapply дан пустой список, функция никогда не вызывается. Поэтому он должен придумать тип и по умолчанию он равен list.

... Именно по этой причине (и для производительности) была введена vapply! Требуется указать тип возвращаемого значения (и длину). Это позволяет ему делать правильные вещи. В качестве бонуса, это также быстрее!

sapply(LETTERS[1:3], function(x) {x == "B"}) # F, T, F
sapply(LETTERS[0], function(x) {x == "B"})   # list()

vapply(LETTERS[1:3], function(x) {x == "B"}, logical(1)) # F, T, F
vapply(LETTERS[0], function(x) {x == "B"}, logical(1))   # logical()

Подробнее см. ?vapply.

6 голосов
/ 12 марта 2012

Справка для функции ?sapply содержится в разделе Значение

For ‘sapply(simplify = TRUE)’ and ‘replicate(simplify = TRUE)’: if
‘X’ has length zero or ‘n = 0’, an empty list.

В обоих случаях:

> length(NULL)
[1] 0
> length(vector())
[1] 0

Следовательно sapply()возвращает:

> sapply(vector(), function(x) {x == "B"})
list()
> sapply(NULL, function(x) {x == "B"})
list()

Ваша ошибка не из sapply(), а из [, как показано:

> a[list()]
Error in a[list()] : invalid subscript type 'list'

Так что проблема связана с тем, как поднаборы NULLпустой вектор (vector()) выполняется.Ничего общего с sapply().В обоих случаях он возвращает согласованный вывод, пустой список.

2 голосов
/ 12 марта 2012

На самом деле они оба возвращают list.Единственное различие между ними состоит в том, что при попытке индексировать NULL он всегда возвращает NULL (даже если ваш индекс был списком), но когда вы пытаетесь проиндексировать пустой вектор, он проверяет индекс и понимает, что этоlist.

a = NULL
res = sapply(a, function(x) x == "B") # Res is an empty list
a[res] # returns NULL, because any index of NULL is NULL.


a = vector()
res = sapply(a, function(x) x == "B") # Still an empty list.
a[res] # but you can't index a vector with a list!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...