Есть ли функция R для проверки того, является ли значение допустимым индексом в векторе или списке? - PullRequest
0 голосов
/ 28 мая 2020

Существует несколько способов индексирования i R, например, путем выбора с использованием положительных целых чисел, путем исключения с использованием отрицательных целых чисел, путем выбора с использованием логических выражений / условий, путем выбора с использованием имен (векторов-символов) в именованном векторе или списке и, возможно, много других способов кроме этого. Я хочу, чтобы функция, принимающая два входа ix и lst, сообщала мне, имеет ли значение ix как индекс lst, т.е. что lst[ix] имеет смысл.

Я уже знаю вы можете сделать что-то вроде

is.index <- function(ix,lst){
  ans = FALSE
  try({ans=all(!is.na(lst[ix]))},silent = TRUE)
  return(ans)
}

Но я хочу, чтобы он работал, когда список содержит NA s, а когда это lst список, он работает по-другому. Оба эти случая я, вероятно, легко мог бы рассматривать как особые, но я чувствую, что не знаю всех возможных способов индексирования и всех их тонкостей, поэтому у меня нет возможности узнать, все ли я прибил. особые случаи.

Я знаю, что термин «осмысленный» не совсем хорошо определен, но мне кажется разумным, что существует функция или, по крайней мере, несколько простой способ определить, является ли индекс разумно.

Так есть ли функция или простой способ сделать это, желательно не то, что требует попытки или оператора catch?

EDIT: Я понимаю, что Я не ясно сформулировал свой вопрос. Даже если ix является вектором, я хочу знать, имеет ли lst[ix] смысл, а не вектор, говорящий мне, имеет ли lst[ix[i]] смысл для различных возможных значений i. Желательно, чтобы независимо от типа ix и lst функция всегда могла возвращать одно логическое значение, т.е. TRUE или FALSE. Например, если lst = 1:5 и ix = c(-1,2) должны возвращать FALSE, а не c(TRUE,TRUE).

Дальнейшее уточнение: Лично мне не нравится частичное сопоставление или то, что имеет смысл индексировать нецелые числа с двойной точностью (мне даже меньше нравится то, что он просто использует целую часть (а не, например, округление до ближайшего целого числа (полезно при небольших ошибках точности) или выступление (делает lst[x/y] = lst[x%/%y]))); но так как R имеет смысл, я думаю, что предпочтение ответчика должно быть решено, возвращать ли TRUE или FALSE в этих ситуациях. То же самое касается lst[0] и lst[NA], тогда как, поскольку list("Cheese" = 4)["Che"] дает NA, я не думаю, что следует принимать частичное соответствие.

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

1 Ответ

1 голос
/ 29 мая 2020

Кажется, что-то вроде следующего работает. Он использует частичное сопоставление для сопоставления символа ix с именами векторов или списков.

is.index <- function(X, ix){
  if(is.character(ix)){
    if(is.null(names(X))) FALSE
    !is.na(pmatch(ix, names(X)))
  }else{
    abs(ix) <= length(X)
  }
}

Тест с векторами.

x <- 1:6
y <- setNames(x, letters[x])
is.index(x, 2)
is.index(x, 7)
is.index(x, -3)
is.index(y, 'a')
is.index(y, 'z')

А теперь со списками.

lst <- list(1:6, letters[1:4])
is.index(lst, 3)
is.index(lst, "a")
is.index(lst, -1)

Но есть проблемы, частичное соответствие работает только с функцией извлечения $, оно не работает с [[, даже с [.

lst2 <- setNames(lst, c("A", "2nd"))
is.index(lst2, "A")

is.index(lst2, "2n")
lst2$`2n`              # works
lst[['2n']]            # fails
...