我有一个简单的表格,数字递减,并有一列交替的“是” /“否”。
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中的表时,它说第三行的值是数字,所以我不知道问题出在哪里。
答案 0 :(得分:1)
我们可以将dplyr
与rowwise
一起使用,这非常简单。
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