R - 制作二元变量的函数

3

我的一些变量的取值范围在1到5之间。如果它们的取值在1到3之间(包括3),我想将它们编码为0,如果它们的取值是4或5,则编码为1

我的数据集看起来像这样:

var1    var2        var3
1       1            NA
4       3            4
3       4            5
2       5            3

所以我希望它能像这样:

var1    var2        var3
0       0            NA
1       0            1
0       1            1
0       1            0

我尝试编写一个函数并调用它

making_binary <- function (var){
  var <- factor(var >= 4, labels = c(0, 1))
  return(var)
}


df <- lapply(df, making_binary)

但我遇到了一个错误:不正确的标签:长度为2必须是1或1

我哪里出错了? 非常感谢您的回答!

3个回答

4

你可以使用:

df[] <- +(df == 4 | df == 5)
df
#  var1 var2 var3
#1    0    0   NA
#2    1    0    1
#3    0    1    1
#4    0    1    0

df == 4 | df == 5 的比较结果是逻辑值(TRUE/FALSE),+ 在这里将逻辑值转换为整数值(分别是 1/0)。

如果你想在选择的列上应用此操作,可以通过位置或名称来选择子集列。

cols <- 1:3 #Position
#cols <- grep('var', names(df)) #Name
df[cols] <- +(df[cols] == 4 | df[cols] == 5)

就您的功能而言,您可以执行以下操作:

making_binary <- function (var){
  var <- as.integer(var >= 4)
  #which is faster version of
  #var <- ifelse(var >= 4, 1, 0)
  return(var)
}

df[] <- lapply(df, making_binary)

数据

df <- structure(list(var1 = c(1L, 4L, 3L, 2L), var2 = c(1L, 3L, 4L, 
5L), var3 = c(NA, 4L, 5L, 3L)), class = "data.frame", row.names = c(NA, -4L))

我不能这样做,因为我有很多其他变量,我不想改变它们。 - Emeline
1
有趣。请问一下,这个前导的 + 是什么意思? - Stéphane Laurent
1
@Emeline 如果你只想更改第一列和第二列,请将 df[] 更改为 df[, c(1:2)] - Nico
1
感谢您回答了我许多问题,并且总是让初学者能够轻松理解!我真的因为您(和其他来自Stackoverflow的人)而得到了提高。 - Emeline
1
@Emeline 有几种方法可以将函数应用于选定的列。请参见答案的编辑,其中显示了其中的一些方法。 - Ronak Shah

1

我认为ifelse很适合这个问题:

df[] <- lapply(df, function(x) ifelse(x >=1 & x <=3, 0, x))
df
  var1 var2 var3
1    0    0   NA
2    4    0    4
3    0    4    5
4    0    5    0
df[] <- lapply(df, function(x) ifelse(x >=4 & x <=5, 1, x))

df
  var1 var2 var3
1    0    0   NA
2    1    0    1
3    0    1    1
4    0    1    0

如果您需要同时执行两个步骤,可以查看dplyr::case_when()data.table::fcase()


谢谢!这是一个不错的简单方法来完成它! - Emeline

1
你可以简单地测试值是否大于3,这将返回TRUEFALSE并将其转换为数字:
+(x>3)
#     var1 var2 var3
#[1,]    0    0   NA
#[2,]    1    0    1
#[3,]    0    1    1
#[4,]    0    1    0

如果您只需要针对某些列进行操作,您需要将它们子集化。例如,对于第一列和第二列:
+(x[1:2]>3)
#+(x[c("var1","var2")]>3)  #Alternative
#     var1 var2
#[1,]    0    0
#[2,]    1    0
#[3,]    0    1
#[4,]    0    1

数据:

x <- data.frame(var1 = c(1L, 4L, 3L, 2L), var2 = c(1L, 3L, 4L, 5L)
              , var3 = c(NA, 4L, 5L, 3L))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接