我正在执行多层次分析,为了检查统计工件,我想创建新的组级变量,向一些组级变量(如学校级社会经济组成)添加随机噪声。在R中,jitter()函数允许轻松地向列添加随机噪声:
R
jitter()
jittered_variable <- jitter(variable)
但是,此函数会向组内的组级别变量添加不同的值。在R中,是否有任何方法可以将相同的随机噪声添加到组内的组水平变量中?例如,组1的所有成员为+0.5,组2的所有成员为-0.3,依此类推。
9q78igpj1#
这里有一个办法。创建一个命名向量,其中随机值的数量与组的数量相同。名称是定义组的值。然后将随机值match与这些名称的数据相加。
match
df1 <- iris[4:5] set.seed(2023) ngroups <- length(unique(df1$Species)) noise <- jitter(rep(0, ngroups)) noise <- setNames(noise, unique(df1$Species)) noise #> setosa versicolor virginica #> -0.001335442 -0.006592362 -0.013487298 df1$newcol <- df1$Petal.Width + noise[match(df1$Species, names(noise))] # these differences are the random noise values df1$newcol - df1$Petal.Width #> [1] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [6] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [11] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [16] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [21] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [26] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [31] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [36] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [41] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [46] -0.001335442 -0.001335442 -0.001335442 -0.001335442 -0.001335442 #> [51] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [56] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [61] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [66] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [71] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [76] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [81] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [86] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [91] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [96] -0.006592362 -0.006592362 -0.006592362 -0.006592362 -0.006592362 #> [101] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [106] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [111] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [116] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [121] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [126] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [131] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [136] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [141] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298 #> [146] -0.013487298 -0.013487298 -0.013487298 -0.013487298 -0.013487298
创建于2023-04-02使用reprex v2.0.2
6ojccjat2#
我将假设一个runif抖动,尽管这个方法也可以与其他函数/参数一起工作(经过修改)。使用分组变量和抖动参数创建帧,例如
runif
jitters <- data.frame( cyl = c(4L, 6L, 8L), neg = c(0, -0.3, -0.1), pos = c(0.5, 0, 0.1) ) jitters # cyl neg pos # 1 4 0.0 0.5 # 2 6 -0.3 0.0 # 3 8 -0.1 0.1
从这里开始,我们可以用一个简单的方法一次在所有变量上执行runif:
set.seed(42) out <- merge(mtcars, jitters, by = "cyl", all.x = TRUE) |> transform(mpg2 = mpg + runif(nrow(mtcars), neg, pos)) out # cyl mpg disp hp drat wt qsec vs am gear carb neg pos mpg2 # 1 4 22.8 140.8 95 3.92 3.150 22.90 1 0 4 2 0.0 0.5 23.25740 # 2 4 22.8 108.0 93 3.85 2.320 18.61 1 1 4 1 0.0 0.5 23.26854 # 3 4 24.4 146.7 62 3.69 3.190 20.00 1 0 4 2 0.0 0.5 24.54307 # 4 4 21.5 120.1 97 3.70 2.465 20.01 1 0 3 1 0.0 0.5 21.91522 # 5 4 30.4 75.7 52 4.93 1.615 18.52 1 1 4 2 0.0 0.5 30.72087 # 6 4 33.9 71.1 65 4.22 1.835 19.90 1 1 4 1 0.0 0.5 34.15955 # 7 4 26.0 120.3 91 4.43 2.140 16.70 0 1 5 2 0.0 0.5 26.36829 # 8 4 30.4 95.1 113 3.77 1.513 16.90 1 1 5 2 0.0 0.5 30.46733 # 9 4 32.4 78.7 66 4.08 2.200 19.47 1 1 4 1 0.0 0.5 32.72850 # 10 4 21.4 121.0 109 4.11 2.780 18.60 1 1 4 2 0.0 0.5 21.75253 # 11 4 27.3 79.0 66 4.08 1.935 18.90 1 1 4 1 0.0 0.5 27.52887 # 12 6 21.0 160.0 110 3.90 2.620 16.46 0 1 4 4 -0.3 0.0 20.91573 # 13 6 21.0 160.0 110 3.90 2.875 17.02 0 1 4 4 -0.3 0.0 20.98040 # 14 6 17.8 167.6 123 3.92 3.440 18.90 1 0 4 4 -0.3 0.0 17.57663 # 15 6 21.4 258.0 110 3.08 3.215 19.44 1 0 3 1 -0.3 0.0 21.23869 # 16 6 18.1 225.0 105 2.76 3.460 20.22 1 0 3 1 -0.3 0.0 18.08200 # 17 6 19.2 167.6 123 3.92 3.440 18.30 1 0 4 4 -0.3 0.0 19.19347 # 18 6 19.7 145.0 175 3.62 2.770 15.50 0 1 5 6 -0.3 0.0 19.43525 # 19 8 18.7 360.0 175 3.15 3.440 17.02 0 0 3 2 -0.1 0.1 18.69500 # 20 8 17.3 275.8 180 3.07 3.730 17.60 0 0 3 3 -0.1 0.1 17.31207 # 21 8 14.3 360.0 245 3.21 3.570 15.84 0 0 3 4 -0.1 0.1 14.38081 # 22 8 14.7 440.0 230 3.23 5.345 17.42 0 0 3 4 -0.1 0.1 14.62774 # 23 8 10.4 472.0 205 2.93 5.250 17.98 0 0 3 4 -0.1 0.1 10.49778 # 24 8 16.4 275.8 180 3.07 4.070 17.40 0 0 3 3 -0.1 0.1 16.48933 # 25 8 19.2 400.0 175 3.08 3.845 17.05 0 0 3 2 -0.1 0.1 19.11649 # 26 8 15.2 275.8 180 3.07 3.780 18.00 0 0 3 3 -0.1 0.1 15.20284 # 27 8 15.2 304.0 150 3.15 3.435 17.30 0 0 3 2 -0.1 0.1 15.17804 # 28 8 10.4 460.0 215 3.00 5.424 17.82 0 0 3 4 -0.1 0.1 10.48115 # 29 8 15.8 351.0 264 4.22 3.170 14.50 0 1 5 4 -0.1 0.1 15.78939 # 30 8 15.5 318.0 150 2.76 3.520 16.87 0 0 3 2 -0.1 0.1 15.56720 # 31 8 15.0 301.0 335 3.54 3.570 14.60 0 1 5 8 -0.1 0.1 15.04752 # 32 8 13.3 350.0 245 3.73 3.840 15.41 0 0 3 4 -0.1 0.1 13.36221
如果你需要一个不同的函数,而 that 函数不能像这样向量化参数,你可能需要Vectorize(func)(nrow(mtcars), neg, pos)或类似的函数,尽管这会降低速度(对于大数据)。我们可以通过以下方式“验证”(在合理范围内)抖动:
Vectorize(func)(nrow(mtcars), neg, pos)
aggregate(cbind(mpg, mpg2) ~ cyl, data = out, FUN = function(z) c(min = min(z), max = max(z))) # cyl mpg.min mpg.max mpg2.min mpg2.max # 1 4 21.4 33.9 21.61789 34.00383 # 2 6 17.8 21.4 17.78727 21.36633 # 3 8 10.4 19.2 10.30779 19.23546
其中对于cyl == 4,由于-0, +0.5的范围,我们期望mpg.min <= mpg2.min;对于cyl == 6和-0.3, +0的范围,我们期望mpg.max >= mpg2.max;等等
cyl == 4
-0, +0.5
mpg.min <= mpg2.min
cyl == 6
-0.3, +0
mpg.max >= mpg2.max
2条答案
按热度按时间9q78igpj1#
这里有一个办法。
创建一个命名向量,其中随机值的数量与组的数量相同。名称是定义组的值。然后将随机值
match
与这些名称的数据相加。创建于2023-04-02使用reprex v2.0.2
6ojccjat2#
我将假设一个
runif
抖动,尽管这个方法也可以与其他函数/参数一起工作(经过修改)。使用分组变量和抖动参数创建帧,例如
从这里开始,我们可以用一个简单的方法一次在所有变量上执行
runif
:如果你需要一个不同的函数,而 that 函数不能像这样向量化参数,你可能需要
Vectorize(func)(nrow(mtcars), neg, pos)
或类似的函数,尽管这会降低速度(对于大数据)。我们可以通过以下方式“验证”(在合理范围内)抖动:
其中对于
cyl == 4
,由于-0, +0.5
的范围,我们期望mpg.min <= mpg2.min
;对于cyl == 6
和-0.3, +0
的范围,我们期望mpg.max >= mpg2.max
;等等