创建一个忽略 NA 的新变量
Create a new variable ignoring NA
我有一个包含多个变量的数据集,这些变量代表患者、实验室 ID 和结果。它看起来像这样:
id lab.1 result.1 lab.2 result.2 lab.3 result.3 lab.4 result.4
1 110 2039 0 2039 0 NA NA NA NA
2 203 1778 5694 1778 908 1778 786 NA NA
3 218 13490 579 13490 276 1067 243 13490 152
4 222 495 0 495 495 0 495 495 0
5 231 1067 966117 306 82794 NA NA NA NA
6 238 2821 89 2821 NA NA NA NA NA
问题是我需要创建一个新变量来指示实验室在所有 'lab' 变量 (0/1) 中是否相同。我期待的结果是这样的:
samelab
1 1
2 1
3 0
4 1
5 0
6 1
但是,许多变量是 NA,我无法弄清楚如何解决它,因为我无法重新编码 NA,因为它意味着什么。
我尝试使用 df$samelab = ifelse(df$lab.1 == df$lab.2 & df$lab.3 & df$lab.4, 1, 0)
但它生成了 NA 结果。
对于解决此问题的任何帮助,我将不胜感激。谢谢!
我们可以使用 grep
对以 'lab' 开头的列进行子集化(或使用 startsWith
)。然后,我们与第一列进行比较,得到逻辑矩阵的rowSums
,检查计数是否等于列数,将逻辑向量变为二进制+
df1 <- df[grep('lab', names(df))]
n1 <- rowSums(df1== df1[,1], na.rm = TRUE)
n2 <- rowSums(!is.na(df1) & df1 != 0)
df$samelab <- +(n1 == n2)
另一种选择是检查 unique
个元素的 length
+(apply(df1, 1, function(x) length(unique(x[!is.na(x)]))) == 1)
如果我们不考虑 0
df$samelab <- +(apply(df1, 1, function(x) length(unique(x[!is.na(x) & x != 0]))) == 1)
df$samelab
#[1] 1 1 0 1 0 1
或带有 tidyverse
的选项
library(dplyr)
df %>%
rowwise %>%
mutate(samelab = as.integer(n_distinct(setdiff(na.omit(c_across(
starts_with('lab'))),
0)) == 1))
-输出
# A tibble: 6 x 10
# Rowwise:
# id lab.1 result.1 lab.2 result.2 lab.3 result.3 lab.4 result.4 samelab
# <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 110 2039 0 2039 0 NA NA NA NA 1
#2 203 1778 5694 1778 908 1778 786 NA NA 1
#3 218 13490 579 13490 276 1067 243 13490 152 0
#4 222 495 0 495 495 0 495 495 0 1
#5 231 1067 966117 306 82794 NA NA NA NA 0
#6 238 2821 89 2821 NA NA NA NA NA 1
我有一个包含多个变量的数据集,这些变量代表患者、实验室 ID 和结果。它看起来像这样:
id lab.1 result.1 lab.2 result.2 lab.3 result.3 lab.4 result.4
1 110 2039 0 2039 0 NA NA NA NA
2 203 1778 5694 1778 908 1778 786 NA NA
3 218 13490 579 13490 276 1067 243 13490 152
4 222 495 0 495 495 0 495 495 0
5 231 1067 966117 306 82794 NA NA NA NA
6 238 2821 89 2821 NA NA NA NA NA
问题是我需要创建一个新变量来指示实验室在所有 'lab' 变量 (0/1) 中是否相同。我期待的结果是这样的:
samelab
1 1
2 1
3 0
4 1
5 0
6 1
但是,许多变量是 NA,我无法弄清楚如何解决它,因为我无法重新编码 NA,因为它意味着什么。
我尝试使用 df$samelab = ifelse(df$lab.1 == df$lab.2 & df$lab.3 & df$lab.4, 1, 0)
但它生成了 NA 结果。
对于解决此问题的任何帮助,我将不胜感激。谢谢!
我们可以使用 grep
对以 'lab' 开头的列进行子集化(或使用 startsWith
)。然后,我们与第一列进行比较,得到逻辑矩阵的rowSums
,检查计数是否等于列数,将逻辑向量变为二进制+
df1 <- df[grep('lab', names(df))]
n1 <- rowSums(df1== df1[,1], na.rm = TRUE)
n2 <- rowSums(!is.na(df1) & df1 != 0)
df$samelab <- +(n1 == n2)
另一种选择是检查 unique
个元素的 length
+(apply(df1, 1, function(x) length(unique(x[!is.na(x)]))) == 1)
如果我们不考虑 0
df$samelab <- +(apply(df1, 1, function(x) length(unique(x[!is.na(x) & x != 0]))) == 1)
df$samelab
#[1] 1 1 0 1 0 1
或带有 tidyverse
library(dplyr)
df %>%
rowwise %>%
mutate(samelab = as.integer(n_distinct(setdiff(na.omit(c_across(
starts_with('lab'))),
0)) == 1))
-输出
# A tibble: 6 x 10
# Rowwise:
# id lab.1 result.1 lab.2 result.2 lab.3 result.3 lab.4 result.4 samelab
# <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 110 2039 0 2039 0 NA NA NA NA 1
#2 203 1778 5694 1778 908 1778 786 NA NA 1
#3 218 13490 579 13490 276 1067 243 13490 152 0
#4 222 495 0 495 495 0 495 495 0 1
#5 231 1067 966117 306 82794 NA NA NA NA 0
#6 238 2821 89 2821 NA NA NA NA NA 1