3

我想知道如何简单地创建一个虚拟变量。我在假人上发现了许多类似的问题,但它们要么基于一些外部软件包,要么基于技术。

我有这样的数据:

df <- data.frame(X=rnorm(10,0,1), Y=rnorm(10,0,1))
df$Z <- c(NA, diff(df$X)*diff(df$Y))

Z 在 df 中创建一个新变量,即 X 变化和 Y 变化的乘积。现在我想在 df 中创建一个虚拟变量 D,如果:Z < 0 则 D==1,如果 Z >0 则 D== 0。

我尝试过这种方式:

df$D <- NA
for(i in 2:10) {
if(df$Z[i] <0 ) {
D[i] ==1
}
if(df$Z[i] >0 ) {
D[i] ==0
}}

这是行不通的。我想知道为什么上面的代码不起作用(通过简单的方法),以及如何在 R 中创建虚拟变量而不使用任何外部包,只需一点解释。

4

3 回答 3

7

尝试 :

df$D<-ifelse(df$Z<0,1,0)
df
            X           Y           Z  D
1  -0.1041896 -1.11731404          NA NA
2  -1.4286604  1.42523717 -3.36753491  1
3   0.3931643 -0.05525477 -2.69719691  1
4  -0.2236541  1.64531526 -1.04894297  1
5   1.1725167  0.80063291 -1.17932089  1
6   0.7571427  0.64072381  0.06642209  0
7   0.4929186  1.25125268 -0.16131645  1
8   0.9715885 -0.54755653 -0.86103574  1
9  -0.2962052 -1.37459521  1.04851438  0
10 -1.4838675 -0.85788632 -0.61367565  1

ifelse函数接受 3 个参数:要评估的条件df$Z<0、条件为TRUE1 时的值和条件为FALSE0 时的值。该函数是矢量化的,因此在这种情况下运行良好。

于 2015-11-12T08:14:19.083 回答
5

我们可以创建一个逻辑向量df$Z < 0,然后通过包装将其强制为二进制+

 df$D <- +(df$Z <0)

或者正如@BenBolker 提到的,规范选项是

as.numeric(df$Z < 0)

或者

as.integer(df$Z < 0)

基准

set.seed(42)
Z <- rnorm(1e7)
library(microbenchmark)
microbenchmark(akrun= +(Z < 0), etienne = ifelse(Z < 0, 1, 0),
           times= 20L,  unit='relative')
#    Unit: relative
#    expr      min       lq     mean   median      uq      max neval
#   akrun  1.00000  1.00000 1.000000  1.00000 1.00000 1.000000    20
# etienne 12.20975 10.36044 9.926074 10.66976 9.32328 7.830117    20
于 2015-11-12T08:12:28.523 回答
1

你可以试试

df$D[df$Z<0]<-1
df$D[df$Z>0]<-0

但是您应该考虑 Z 可能为 0 的可能性。

于 2015-11-12T08:17:46.897 回答