建立具有多种条件的虚拟变量 (R)
Building dummy variable with many conditions (R)
我的数据集看起来像这样
ID YOB ATT94 GRADE94 ATT96 GRADE96 ATT 96 .....
1 1975 1 12 0 NA
2 1985 1 3 1 5
3 1977 0 NA 0 NA
4 ......
(ATTXX 是一个虚拟变量,表示 XX 年的入学率,GRADEXX 表示学校年级)
我正在尝试创建一个虚拟变量,如果一个人在 19/20 岁时上学,则该变量 = 1。例如如果 YOB = 1988 和 ATT98 = 1 那么新变量 = 1 等。我一直在 dplyr 中使用 mutate 尝试这个,但我是 R 的新手(和一般的编码!)所以除了错误之外很难得到任何东西我写的代码。
如有任何帮助,我们将不胜感激。
编辑:
所以,我刚刚注意到出了点问题,我稍微更改了您的代码,只是为了向长格式数据添加另一列 table。这是我最后所做的:
df %>%
melt(id = c("ID", "DOB") %>%
tbl_df() %>%
mutate(dummy = ifelse(value - DOB %in% c(19,20), 1, 0))
所以它看起来像
ID YOB VARIABLE VALUE dummy
1 1979 ATT94 1994 1
1 1979 ATT96 1996 1
1 1979 ATT98 0 0
2 1976 ATT94 0 0
2 1976 ATT96 1996 1
2 1976 ATT98 1998 1
即每当 ATT 变量取 0 以外的值时,虚拟 = 1,即使他们不是 19/20 岁。知道哪里出了问题吗?
在我的 phone 上,所以我现在无法检查,但请尝试:
df$dummy[df$DOB==1988 & df$ATT98==1] <- 1
编辑: 上述方法将创建该列,但当条件不成立时,它将等于 NA
正如@Greg Snow 所提到的,这种方法假定该列已经创建并且最初等于零。因此,您可以执行以下操作来获取您的虚拟变量:
df$dummy <- rep(0, nrow(df))
df$dummy[df$DOB==1988 & df$ATT98==1] <- 1
@Warner 展示了一种创建变量的方法(或者至少假设 1 的列已经设置为 0)。另一种方法是不显式创建虚拟变量,而是在模型语法中为您创建它(您要求的本质上是一种交互)。如果 运行 回归,这将是这样的:
fit <- lm( resp ~ I(DOB==1988):I(ATT98==1), data=df )
或
fit <- lm( resp ~ I( (DOB==1988) & (ATT98==1) ), data=df)
欢迎来到代码世界! R 的语法可能很棘手(即使对于有经验的编码人员也是如此)并且 dplyr
增加了它自己的怪癖。首先,当您提出问题以提供其他人可以 运行 以便能够重现您的数据的代码时,这很有用。您可以了解更多相关信息 here。
您是否正在尝试创建适用于 DOB
和 ATTx
所有可能值的代码?换句话说,您是否有一大堆以 ATT 开头的变量,并且您想查看所有这些变量?这种格式称为宽数据,R 在处理长数据时效果更好。幸运的是 reshape2
包正是这样做的。下面的代码为 19 岁或 20 岁在校的人创建了一个值为 1 的 dummy
变量。
# Load libraries
library(dplyr)
library(reshape2)
# Create a sample dataset
ATT94 <- runif(500, min = 0, max = 1) %>% round(digits = 0)
ATT96 <- runif(500, min = 0, max = 1) %>% round(digits = 0)
ATT98 <- runif(500, min = 0, max = 1) %>% round(digits = 0)
DOB <- rnorm(500, mean = 1977, sd = 5) %>% round(digits = 0)
df <- cbind(DOB, ATT94, ATT96, ATT98) %>% data.frame()
# Recode ATTx variables with the actual year
df$ATT94[df$ATT94==1] <- 1994
df$ATT96[df$ATT96==1] <- 1996
df$ATT98[df$ATT98==1] <- 1998
# Melt the data into a long format and perform requested analysis
df %>%
melt(id = "DOB") %>%
tbl_df() %>%
mutate(dummy = ifelse(value - DOB %in% c(19,20), 1, 0))
我的数据集看起来像这样
ID YOB ATT94 GRADE94 ATT96 GRADE96 ATT 96 .....
1 1975 1 12 0 NA
2 1985 1 3 1 5
3 1977 0 NA 0 NA
4 ......
(ATTXX 是一个虚拟变量,表示 XX 年的入学率,GRADEXX 表示学校年级)
我正在尝试创建一个虚拟变量,如果一个人在 19/20 岁时上学,则该变量 = 1。例如如果 YOB = 1988 和 ATT98 = 1 那么新变量 = 1 等。我一直在 dplyr 中使用 mutate 尝试这个,但我是 R 的新手(和一般的编码!)所以除了错误之外很难得到任何东西我写的代码。
如有任何帮助,我们将不胜感激。
编辑:
所以,我刚刚注意到出了点问题,我稍微更改了您的代码,只是为了向长格式数据添加另一列 table。这是我最后所做的:
df %>%
melt(id = c("ID", "DOB") %>%
tbl_df() %>%
mutate(dummy = ifelse(value - DOB %in% c(19,20), 1, 0))
所以它看起来像
ID YOB VARIABLE VALUE dummy
1 1979 ATT94 1994 1
1 1979 ATT96 1996 1
1 1979 ATT98 0 0
2 1976 ATT94 0 0
2 1976 ATT96 1996 1
2 1976 ATT98 1998 1
即每当 ATT 变量取 0 以外的值时,虚拟 = 1,即使他们不是 19/20 岁。知道哪里出了问题吗?
在我的 phone 上,所以我现在无法检查,但请尝试:
df$dummy[df$DOB==1988 & df$ATT98==1] <- 1
编辑: 上述方法将创建该列,但当条件不成立时,它将等于 NA
正如@Greg Snow 所提到的,这种方法假定该列已经创建并且最初等于零。因此,您可以执行以下操作来获取您的虚拟变量:
df$dummy <- rep(0, nrow(df))
df$dummy[df$DOB==1988 & df$ATT98==1] <- 1
@Warner 展示了一种创建变量的方法(或者至少假设 1 的列已经设置为 0)。另一种方法是不显式创建虚拟变量,而是在模型语法中为您创建它(您要求的本质上是一种交互)。如果 运行 回归,这将是这样的:
fit <- lm( resp ~ I(DOB==1988):I(ATT98==1), data=df )
或
fit <- lm( resp ~ I( (DOB==1988) & (ATT98==1) ), data=df)
欢迎来到代码世界! R 的语法可能很棘手(即使对于有经验的编码人员也是如此)并且 dplyr
增加了它自己的怪癖。首先,当您提出问题以提供其他人可以 运行 以便能够重现您的数据的代码时,这很有用。您可以了解更多相关信息 here。
您是否正在尝试创建适用于 DOB
和 ATTx
所有可能值的代码?换句话说,您是否有一大堆以 ATT 开头的变量,并且您想查看所有这些变量?这种格式称为宽数据,R 在处理长数据时效果更好。幸运的是 reshape2
包正是这样做的。下面的代码为 19 岁或 20 岁在校的人创建了一个值为 1 的 dummy
变量。
# Load libraries
library(dplyr)
library(reshape2)
# Create a sample dataset
ATT94 <- runif(500, min = 0, max = 1) %>% round(digits = 0)
ATT96 <- runif(500, min = 0, max = 1) %>% round(digits = 0)
ATT98 <- runif(500, min = 0, max = 1) %>% round(digits = 0)
DOB <- rnorm(500, mean = 1977, sd = 5) %>% round(digits = 0)
df <- cbind(DOB, ATT94, ATT96, ATT98) %>% data.frame()
# Recode ATTx variables with the actual year
df$ATT94[df$ATT94==1] <- 1994
df$ATT96[df$ATT96==1] <- 1996
df$ATT98[df$ATT98==1] <- 1998
# Melt the data into a long format and perform requested analysis
df %>%
melt(id = "DOB") %>%
tbl_df() %>%
mutate(dummy = ifelse(value - DOB %in% c(19,20), 1, 0))