【问题标题】:Random values repeat when iterated through purrr:map遍历 purrr:map 时随机值重复
【发布时间】:2020-06-15 19:11:11
【问题描述】:

我正在尝试生成空间有限随机游走的“假”数据集,即在每个时间步长,个人将随机移动任意距离 x 和 y,但这些值需要限制在我的竞技场(xlim和 ylim)——我并不特别关心当个人碰到边缘时会发生什么(反射或跟随墙壁),但他们不能越过边缘。

所有代码都会运行,并且函数“walker”在每次单独运行时都会给出新的和不同的值,但是当我通过 purrr::map 将其放入时,这些值只是为每个人重复。

我从几个来源拼凑起来,我相信它可以大大简化 - 最终,我希望 n.times 更大(最终目标是计算时间量*# 个人访问特定的方格),但第一步是让个人拥有不同的移动记录!

library(tidyverse)
n.times<-10
OUT <-data.frame(x.a = vector("numeric", n.times),y.a = vector("numeric", n.times))

walker <- function(n.times,
                   xlim=c(0,100),
                   ylim=c(0,30),
                   start=c(0,0),
                   stepsize=c(1,1)) {
  ## extract starting point
  x <- start[1]
  y <- start[2]
  for (i in 1:n.times) {
    repeat {
      ## pick jump sizes
      xi <- stepsize[1]*sample(rnorm(n = n.times, mean = 0, sd = .5),1)
      yi <- stepsize[2]*sample(rnorm(n = n.times, mean = 0, sd = .5),1)
      ## new candidate locations
      newx <- x+xi
      newy <- y+yi
      ## IF new locations are within bounds, then
      ##    break out of the repeat{} loop (otherwise
      ##    try again)
      if (newx>xlim[1] && newx<xlim[2] &&
          newy>ylim[1] && newy<ylim[2]) break
    }
    ## set new location to candidate location
    x <- newx
    y <- newy
    OUT[i,"x.a"] <-x
    OUT[i, "y.a"] <-y
  }
  return(OUT)
}


#generate fake fish
fish<-data.frame(fish=as.character(letters[1:10]))

#apply walker to fake fish
fishmoves <- fish %>% 
  mutate(data= map(.,~walker(10))) %>% 
  unnest(data)

【问题讨论】:

    标签: r random dplyr purrr


    【解决方案1】:

    当您调用 map 时,它需要遍历与 data.frame 长度相同的数字。您使用了 magrittr .,这将是您案例中的整个 data.frame,将其设为 1,因此复制了 1 值。

    你可以做两件事:

    library(dplyr)
    library(tidyr)
    library(purrr)
    
    res = tibble(fish) %>% mutate(data=map(fish,~walker(10)))
    res$data[1:2]
    
    [[1]]
              x.a       y.a
    1  0.05691327 0.6609499
    2  0.32432701 1.2174572
    3  0.66515689 1.8964721
    4  0.88173958 2.3758121
    5  0.43781208 3.0526259
    6  0.14187217 2.9216027
    7  1.04768003 2.6636641
    8  0.98632704 2.3824672
    9  0.85341917 3.4224993
    10 0.97703491 3.9261718
    
    [[2]]
             x.a       y.a
    1  0.4137715 0.3202513
    2  0.3973849 0.2958951
    3  0.9051333 0.4163088
    4  0.6249996 0.4514562
    5  1.1098010 0.1973155
    6  1.1208103 0.6239122
    7  1.2693395 1.1020321
    8  0.9213216 1.4417686
    9  1.0848714 0.5382004
    10 0.8635316 0.4516631
    

    有点不需要,但如果在以后的代码中你需要按组做某事时很有用:

    fish %>% group_by(fish) %>% mutate(data=map(.,~walker(10)))
    

    顺便说一句,我会考虑将 data.frame OUT 放在函数内。

    【讨论】:

    • 我没有关注第 1 部分中发生的事情——当我运行它时,我遇到了同样的问题,1 和 2 都有相同的数据。像在第 2 部分中所做的那样添加 group_by 对我有用并解决了问题。 OUT 在函数内部,但在 for 循环之外——如果我将 OUT 移到 for 循环内,我只会得到 1 处的值
    • 在函数walker 中声明OUT data.frame,这就是我的意思。我已经用调用的库更新了我的答案。可能是你有什么冲突。 tidyverse 有时可能有点矫枉过正
    • 不,只是一个 dum-dum 并没有注意到您替换了 .与“鱼”。两者现在都在工作。
    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 2019-04-19
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2017-07-11
    相关资源
    最近更新 更多