【问题标题】:sample() in R unpredictable when vector length is one [duplicate]当向量长度为​​ 1 时,R 中的 sample() 不可预测
【发布时间】:2018-01-29 16:36:19
【问题描述】:

我正在尝试调试一个简短的程序,但在某些条件下,我在对向量元素进行采样时得到了令人不安的结果。它发生在向量的元素仍然绘制到单个值时。

在特定情况下,我指的向量称为remaining,并包含一个元素,即数字2。我希望这个向量中任何大小为 1 的采样都会顽固地返回 2,因为 2 是向量中唯一的元素,但事实并非如此:

Browse[2]> is.vector(remaining)
[1] TRUE
Browse[2]> sample(remaining,1)
[1] 2
Browse[2]> sample(remaining,1)
[1] 2
Browse[2]> sample(remaining,1)
[1] 1
Browse[2]> sample(x=remaining, size=1)
[1] 1
Browse[2]> sample(x=remaining, size=1)
[1] 2
Browse[2]> sample(x=remaining, size=1)
[1] 1
Browse[2]> sample(x=remaining, size=1)
[1] 1
Browse[2]> sample(x=remaining, size=1)
[1] 1

如您所见,有时返回是1,而其他一些返回是2

我对函数sample()有什么误解?

【问题讨论】:

  • Browse[2]> all(remaining==2) [1] TRUE

标签: r random sample


【解决方案1】:

来自help("sample")

如果 x 的长度为 1,是数字(在 is.numeric 的意义上)并且 x >= 1, 通过 sample 进行采样从 1:x 开始。

所以,当你有remaining = 2,那么sample(remaining) 就等于sample(x = 1:2)

更新

从 cmets 可以看出,您也在寻找解决此行为的方法。以下是上述三种替代方案的基准比较:

library(microbenchmark)

# if remaining is of length one
remaining <- 2

microbenchmark(a = {if ( length(remaining) > 1 ) { sample(remaining) } else { remaining }},
               b = ifelse(length(remaining) > 1, sample(remaining), remaining),
               c = remaining[sample(length(remaining))])

Unit: nanoseconds
 expr  min   lq    mean median     uq   max neval cld
    a  349  489  625.12  628.0  663.5  3283   100 a  
    b 1536 1886 2240.58 2025.0 2165.5 13898   100  b 
    c 4051 4400 5193.41 4679.5 5064.0 38413   100   c

# If remaining is not of length one
remaining <- 1:10
microbenchmark(a = {if ( length(remaining) > 1 ) { sample(remaining) } else { remaining }},
               b = ifelse(length(remaining) > 1, sample(remaining), remaining),
               c = remaining[sample(length(remaining))])

Unit: microseconds
 expr    min      lq     mean median      uq    max neval cld
    a  5.238  5.7970  6.82703  6.251  6.9145 51.264   100  a 
    b 11.663 12.2920 13.14831 12.851 13.3745 34.851   100   b
    c  5.238  5.9715  6.57140  6.426  6.8450 14.667   100  a 

如果remaining 的长度> 1 时更频繁地调用sample(),那么看起来joran 的建议可能是最快的,否则if() {} else {} 方法会更快。

【讨论】:

  • 我读到了,但我不确定它是什么意思,或者如何解决它。
  • 你应该检查剩余长度是否为1,在这种情况下避免采样。
  • @Toni 这种行为是因为从长度为 1 的向量中采样没有意义;只有一个可能的答案,那就是向量本身,甚至不是从向量派生的某个值。
  • @aocall 这意味着在代码中增加一两行。应该有一种方法可以解决 sample() 函数的这种非常混乱的行为......
  • @Toni 也许类似于if ( length(remaining) &gt; 1 ) { sample(remaining) } else { remaining },因为您不需要ifelse() 的矢量化和减速
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多