每行用rmrm生成的数据运行runif

时间:2018-10-15 04:25:36

标签: r dataframe

我有一个简单的表格,数字递减,并有一列交替的“是” /“否”。

dat <- data.frame(a = c(8,8,6,6,4,4,2,2),
                  b = rep(c("yes", "no"), 4))

| 8 | "yes"
| 8 | "no"
| 6 | "yes"
| 6 | "no"
.. goes down to 2 | "no"

然后,我使用rnorm根据“是”或“否”,逐行为该表生成另一列。

dat$total_time = apply(dat, 1, 
 function(x) round( rnorm(1, mean=ifelse(x[2] == "yes", 140, 120), sd=10), 1))

这给了我一张类似的表格:

| 8 | "yes" | 148.3
| 8 | "no"  | 135.9
etc.

我现在想要的是每行创建另一列,并为每行从(x-30,x)范围中获得一个随机数,其中x是第三行中新生成的数字。

我尝试过:

dat$test_time = apply(dat, 1, function(x) runif(1, x[3]-30, x[3]))

但是我得到了错误:

  

x [3]-30中的错误:二进制运算符的非数字参数

如果我只尝试

runif(1, 0, x[3])

我还是

  

runif(1,0,x [3])中的错误:参数无效

但是当我单击R studio中的表时,它说第三行的值是数字,所以我不知道问题出在哪里。

1 个答案:

答案 0 :(得分:1)

我们可以将dplyrrowwise一起使用,这非常简单。

library(dplyr)

dat %>%
  rowwise() %>%
  mutate(y =  round(rnorm(1, mean = ifelse(b == "yes", 140, 120), sd=10), 1), 
         z =  runif(1, y-30, y))


#     a  b       y     z
#  <dbl> <fct> <dbl> <dbl>
#1     8 yes   150.  131. 
#2     8 no    114.  111. 
#3     6 yes   142.  113. 
#4     6 no    123.  105. 
#5     4 yes   152.  135. 
#6     4 no    91.6  72.4
#7     2 yes   151.  140. 
#8     2 no    129.  127. 

apply函数的问题在于它将数据帧转换为矩阵,而矩阵只能容纳一种类型的值,因此它将所有数字变量都转换为字符,并且在向字符添加数字时会出现错误。例如,请参见

"2" + 3
  

“ 2” + 3中的错误:二进制运算符的非数字参数

为避免这种情况,您可以在apply调用函数中将数字转换为数字,然后使用它

dat$test_time <- apply(dat, 1, function(x) 
        runif(1, as.numeric(x[3])-30, as.numeric(x[3])))


dat
#  a   b total_time test_time
#1 8 yes      133.0 132.61189
#2 8  no      115.2 114.26407
#3 6 yes      133.6 113.91254
#4 6  no      123.1 113.96119
#5 4 yes      121.3 104.90344
#6 4  no      107.5  80.98989
#7 2 yes      146.1 139.92842
#8 2  no      112.8 104.24055