Как я могу написать функцию, которая возвращает нечетные числа только из списка целых чисел, используя язык R? - PullRequest
0 голосов
/ 09 марта 2019

Как я могу написать функцию, которая возвращает нечетные числа только из списка целых чисел, используя язык R? Пока я пробовал это

 function3 <- function(x){
      x<-as.integer(x)
      if (x %% 2 ==1) {
          return(x)
      }
    }

но это не работает для списков или векторов, и я действительно не знаю, как изменить свой код, так как «если» будет жаловаться на условие> «имеет длину> 1», и будет только первый элемент б

1 Ответ

2 голосов
/ 09 марта 2019
justodd <- function(x) x[ x %% 2 == 1 ]
justodd(4:20)
# [1]  5  7  9 11 13 15 17 19

Пояснение:

  • Индексация описана в ?Extract (также в ?[), вы увидите, что она принимает либо список integer (или целочисленный numeric), либо logical. Если первое, числа должны быть в пределах длины вектора; если последний, то он должен быть той же длины, что и исходный вектор. Например,

    x <- 4:20
    x[c(3,5,1)]
    # [1] 6 8 4
    x[c(F,F,T,F,T,F,F,F,T,F,F,F,F,F,F,F,F)]
    # [1]  6  8 12
    
  • так что наши [ -нутри выглядят как

    x %% 2 == 1
    #  [1] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
    # [13] FALSE  TRUE FALSE  TRUE FALSE
    
  • затем мы индексируем исходный вектор x на основе этого возвращаемого значения


Обновление

Ваше упоминание о том, что он не работает с list в качестве аргумента, предлагает альтернативу, которая является более медленной, но работает как с векторами, так и со списками.

justodd2 <- function(x) Filter(function(a) a %% 2 == 1, x)
vec <- 4:20
lst <- as.list(4:20)
str(vec)
#  int [1:17] 4 5 6 7 8 9 10 11 12 13 ...
str(lst)
# List of 17
#  $ : int 4
#  $ : int 5
#  $ : int 6
#  $ : int 7
#  $ : int 8
#  $ : int 9
#  $ : int 10
#  $ : int 11
#  $ : int 12
#  $ : int 13
#  $ : int 14
#  $ : int 15
#  $ : int 16
#  $ : int 17
#  $ : int 18
#  $ : int 19
#  $ : int 20
justodd2(vec)
# [1]  5  7  9 11 13 15 17 19
justodd2(lst)
# [[1]]
# [1] 5
# [[2]]
# [1] 7
# [[3]]
# [1] 9
# [[4]]
# [1] 11
# [[5]]
# [1] 13
# [[6]]
# [1] 15
# [[7]]
# [1] 17
# [[8]]
# [1] 19

Сравнение производительности:

microbenchmark::microbenchmark(
  a = justodd(vec),
  b = justodd2(vec),
  c = justodd2(lst)
)
# Unit: nanoseconds
#  expr   min    lq  mean median    uq     max neval
#     a   800  1000 26642   1100  1200 2537700   100
#     b 12100 12500 24154  12700 13150 1055600   100
#     c 12100 12300 23777  12500 12800 1022900   100

(Игнорируйте высокие значения mean и max от microbenchmark, они часто смещены при сборке мусора во внутренних органах R. Если вы не знаете, что это такое ... просто нажмите [I believe] Кнопка или Google.)

Итак, в конечном итоге, если вы всегда имеете дело с векторами, то я предлагаю первое justodd решение, в противном случае justodd2 безопаснее (так как justodd(lst) терпит неудачу).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...