将R中的二元变量合并为一个新变量

4

我有三个分类变量,即中风(stroke),心肌梗塞(MI)和高血压(BP),其中0表示“是”,1表示“否”。我想将它们合并成一个新变量"cvd",使每行中的0值在新的心血管变量中也是0。例如:

Stroke  MI  BP  CVD
0       1    1   0
1       1    1   1
1       1    0   0

我尝试了以下代码,但这不是我想要的

transform(koratest, cvd=paste(stroke,MI, BP))

有人可以帮忙提供这个脚本的代码吗?

最好的,

感谢您提供的所有解决方案。如果要合并的任何值中存在缺失值,该怎么办?我想将缺失值标记为1,但如果存在0和缺失值,则我希望cvd变量具有值1。例如:

 Stroke  MI  BP  CVD
0       1    1   0
1       NA   NA  1
0       NA   1   0

我该如何实现这样的输出?

8个回答

2

请尝试,

(rowSums(df) == ncol(df)) * 1
#[1] 0 1 0

这看起来不错。谢谢。但是我的数据集还有其他变量的列表。我应该如何在脚本中选择这三个变量,并在哪里定义新变量的名称? - Hasan Sohail
如果它们是您数据框中的前3个,则为df[1:3]或它们在您的df上找到的索引。 - Sotos

1

另一种方法:

library(dplyr)

df <- data.frame(Stroke = c(0,1,1),
                   MI = c(1,1,1),
                   BP = c(1,1,0))

df %>% 
  rowwise() %>% 
  mutate(
    CVD = min(Stroke, MI, BP) 
  ) %>% 
  ungroup()

#> # A tibble: 3 × 4
#>   Stroke    MI    BP   CVD
#>    <dbl> <dbl> <dbl> <dbl>
#> 1      0     1     1     0
#> 2      1     1     1     1
#> 3      1     1     0     0

本文创建于2022-07-11,使用reprex软件包(v2.0.1)


1

使用 dplyrrowwise 函数来尝试这个问题。

library(dplyr)

df |> rowwise() |> mutate(CVD = if(all(c_across() == 1)) 1 else 0) |> ungroup()
  • 输出
# A tibble: 3 × 4
# Rowwise: 
  Stroke    MI    BP   CVD
   <int> <int> <int> <dbl>
1      0     1     1     0
2      1     1     1     1
3      1     1     0     0

3
你或许想要添加一个 ungroup函数来将其转换为普通的 tbl_df 对象。 - shafee

1

不知道你是如何安排你的变量的。如果它们是分开的向量,那么这个方法应该有效:

Stroke = c(0,1,1)
MI = c(1,1,1)
BP = c(1,1,0)
CVD = as.numeric(Stroke & MI & BP)

如果一个 data.frame
df$CVD = with(df, as.numeric(Stroke & MI & BP)

或者使用其他人提到的解决方案。

0

也许是这样:

library(tidyverse)

Data <- data.frame(Stroke = c(0,1,1),
                   MI = c(1,1,1),
                   BP = c(1,1,0))

Data <- Data %>% 
  mutate(CVD = if_else(Stroke == 1 &MI == 1 & BP == 1, 1, 0))

0

基础 R 选项:

df$CVD <- apply(df,2, function(x) !any(0 %in% x)) + 0
df

输出:

  Stroke MI BP CVD
1      0  1  1   0
2      1  1  1   1
3      1  1  0   0

这个问题的另一个方面是:如果我要合并的变量中有任何缺失值,我该如何处理。详细信息已在问题中编辑。 - Hasan Sohail

0

在使用 cbind 函数时,使用 rowSums 可以检测到 dat 是一个数据框并创建这样的数据框。

cbind(dat, CVD=+(rowSums(dat[c('Stroke', 'MI', 'BP')]) == 3))
#   Stroke MI BP CVD
# 1      0  1  1   0
# 2      1  1  1   1
# 3      1  1  0   0

如果你只有这些列,它就简化为:

cbind(dat, CVD=+(rowSums(dat) == 3))

数据:

dat <- structure(list(Stroke = c(0L, 1L, 1L), MI = c(1L, 1L, 1L), BP = c(1L, 
1L, 0L)), class = "data.frame", row.names = c(NA, -3L))

0
另一种解决你的问题的方法是:
df$CVD = with(df, pmin(Stroke, MI, BP)) 

  Stroke MI BP CVD
1      0  1  1   0
2      1  1  1   1
3      1  1  0   0

# or
library(data.table)

setDT(df)[, CVD := pmin(Stroke, MI, BP)]

# or
library(dplyr)

df = df %>% 
  mutate(CVD = pmin(Stroke, MI, BP))

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