【问题标题】:How can I write a function that returns odd numbers only from a list of integers, using R language?如何使用 R 语言编写一个仅从整数列表中返回奇数的函数?
【发布时间】:2019-03-09 19:03:57
【问题描述】:

如何使用 R 语言编写一个仅从整数列表中返回奇数的函数? 到目前为止我试过这个

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

但它不适用于列表或向量,而且我真的不知道如何更改我的代码,因为“if”会抱怨条件 >“has length > 1”并且只有第一个元素是用过

【问题讨论】:

  • function(x) x[ x %% 2 == 1 ]。你的代码有一些问题:如果x 是一个向量,那么你的if 会抱怨the condition has length &gt; 1 and only the first element will be used,并且由于你没有删除非奇数元素,它返回输入参数。 (唯一的变化是我推断您打算将其整数化,尽管您确实需要x &lt;- as.integer(x)。)
  • 非常感谢,这是一个错字,这解释了第一条错误消息。现在我的代码适用于单个整数;我想使用列表(向量)并让我的函数只返回列表中的奇数元素,但我真的不知道该怎么做。
  • 我的评论在前 28 个字符中有答案。您唯一需要添加的是是否需要转换为整数。
  • 这个问题至少有一部分与stackoverflow.com/q/23316161/3358272stackoverflow.com/q/14170778/3358272 重复。您最初关于如何返回奇数的问题不足以第一次知道它是重复的。

标签: r function


【解决方案1】:
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
    
  • 所以我们的[-insides 看起来像

    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

(忽略来自microbenchmark 的高meanmax 值,它们经常受到R 内部垃圾收集的影响。如果你不知道那是什么......只需按@987654338 @按钮或谷歌它。)

所以最终,如果你总是处理向量,那么我建议第一个justodd 解决方案,否则justodd2 更安全(因为justodd(lst) 失败)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 2011-01-19
    • 2012-12-25
    • 1970-01-01
    相关资源
    最近更新 更多