【问题标题】:runif on rnorm-generated data per-rowrunif 对每行 rnorm 生成的数据
【发布时间】:2018-10-15 13:02:53
【问题描述】:

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

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中点击表格时,它说第三行的值是数字,所以我不知道是什么问题。

【问题讨论】:

    标签: r dataframe


    【解决方案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
    

    【讨论】:

    • 谢谢!有没有办法将 %>% 运算符的输出分配给变量?
    • @blurry 你可以使用df1 &lt;- dat %&gt;% rowwise() %&gt;% mutate(y = round(rnorm(1, mean = ifelse(b == "yes", 140, 120), sd=10), 1), z = runif(1, y-30, y)),然后使用df1
    猜你喜欢
    • 2016-05-23
    • 2014-12-05
    • 2016-10-22
    • 1970-01-01
    • 2018-02-22
    • 2021-08-14
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多