如何使用 mutate_at 和嵌套的 ifelse 语句自动重新编码许多变量?
How to automate recoding of many variables using mutate_at and nested ifelse statement?
有一个大型数据集,由对每个受试者的相同变量的重复测量组成。示例数据如下
df<-data.frame(
"id"=c(1:5),
"ax1"=c(1,6,8,15,17),
"bx1"=c(2,16,8,15,17))
其中 "x1" 被重复测量,因此我们可以有 "ax1"、"bx1"、"cx1" 等等。我正在尝试重新编码这些变量。计划是将 1 和 3 到 12(含)范围内的任何数字重新编码为 0,并将 2 或任何大于或等于 13 的值重新编码为 1。因为它涉及很多变量,所以我正在使用 "mutate_at" 自动重新编码。此外,采用相同代码的数字不是连续的(例如 1 和 3-12 被重新编码为 0)所以我使用了嵌套的 "ifelse" 语句。我尝试了以下
df1<-df %>%
mutate_at(vars(ends_with("x1")),factor,
ifelse(x1>=3 & x1 <=12,0,ifelse(x1==1, 0,
ifelse(x1==2, 1,0))))
然而,这无法工作,因为 R 无法识别 "x1"。提前非常感谢对此的任何帮助。预期的输出看起来像
> df1
id ax1 bx1
1 1 0 1
2 2 0 1
3 3 0 0
4 4 1 1
5 5 1 1
使用ifelse
,我们可以进行如下处理:
df %>%
mutate_at(vars(ends_with("x1")),~ifelse(. ==1 | . %in% 3:12,0,
ifelse(. ==2 | .>=13,1,.)))
id ax1 bx1
1 1 0 1
2 2 0 1
3 3 0 0
4 4 1 1
5 5 1 1
我们可以使用case_when
library(dplyr)
df %>%
mutate_at(vars(ends_with("x1")), ~case_when((. >= 3 & . <= 12) | . == 1 ~ 0,
. >= 13 | . == 2 ~ 1))
# id ax1 bx1
#1 1 0 1
#2 2 0 1
#3 3 0 0
#4 4 1 1
#5 5 1 1
这是另一个类似于您尝试的解决方案。我刚刚添加了 "or" 运算符 (|
) 以简化 ifelse
并从您的代码中删除了 factor
部分。
library(dplyr)
df1<-df %>%
mutate_at(vars(ends_with("x1")), function(x)
ifelse(x >= 3 & x <= 12 | x == 1,0,
ifelse(x >= 13 | x == 2, 1,0)))
# id ax1 bx1
#1 1 0 1
#2 2 0 1
#3 3 0 0
#4 4 1 1
#5 5 1 1
如果除了你提到的条件之外没有其他可能的条件(例如,有零),我认为你可以通过将其简化为以下内容来进一步简化它:
df1<-df %>%
mutate_at(vars(ends_with("x1")), function(x)
ifelse(x >= 3 & x <= 12 | x == 1, 0, 1))
有一个大型数据集,由对每个受试者的相同变量的重复测量组成。示例数据如下
df<-data.frame(
"id"=c(1:5),
"ax1"=c(1,6,8,15,17),
"bx1"=c(2,16,8,15,17))
其中 "x1" 被重复测量,因此我们可以有 "ax1"、"bx1"、"cx1" 等等。我正在尝试重新编码这些变量。计划是将 1 和 3 到 12(含)范围内的任何数字重新编码为 0,并将 2 或任何大于或等于 13 的值重新编码为 1。因为它涉及很多变量,所以我正在使用 "mutate_at" 自动重新编码。此外,采用相同代码的数字不是连续的(例如 1 和 3-12 被重新编码为 0)所以我使用了嵌套的 "ifelse" 语句。我尝试了以下
df1<-df %>%
mutate_at(vars(ends_with("x1")),factor,
ifelse(x1>=3 & x1 <=12,0,ifelse(x1==1, 0,
ifelse(x1==2, 1,0))))
然而,这无法工作,因为 R 无法识别 "x1"。提前非常感谢对此的任何帮助。预期的输出看起来像
> df1
id ax1 bx1
1 1 0 1
2 2 0 1
3 3 0 0
4 4 1 1
5 5 1 1
使用ifelse
,我们可以进行如下处理:
df %>%
mutate_at(vars(ends_with("x1")),~ifelse(. ==1 | . %in% 3:12,0,
ifelse(. ==2 | .>=13,1,.)))
id ax1 bx1
1 1 0 1
2 2 0 1
3 3 0 0
4 4 1 1
5 5 1 1
我们可以使用case_when
library(dplyr)
df %>%
mutate_at(vars(ends_with("x1")), ~case_when((. >= 3 & . <= 12) | . == 1 ~ 0,
. >= 13 | . == 2 ~ 1))
# id ax1 bx1
#1 1 0 1
#2 2 0 1
#3 3 0 0
#4 4 1 1
#5 5 1 1
这是另一个类似于您尝试的解决方案。我刚刚添加了 "or" 运算符 (|
) 以简化 ifelse
并从您的代码中删除了 factor
部分。
library(dplyr)
df1<-df %>%
mutate_at(vars(ends_with("x1")), function(x)
ifelse(x >= 3 & x <= 12 | x == 1,0,
ifelse(x >= 13 | x == 2, 1,0)))
# id ax1 bx1
#1 1 0 1
#2 2 0 1
#3 3 0 0
#4 4 1 1
#5 5 1 1
如果除了你提到的条件之外没有其他可能的条件(例如,有零),我认为你可以通过将其简化为以下内容来进一步简化它:
df1<-df %>%
mutate_at(vars(ends_with("x1")), function(x)
ifelse(x >= 3 & x <= 12 | x == 1, 0, 1))