如何替换多列中不属于另一列值的所有值
How to replace all values in multiple columns that are not among the values in another column
我有一个数据集,其中一个变量带有参与者 ID,多个变量带有同行提名(以 ID 的形式)。
我需要用 NA 替换同行提名变量中所有不在参与者 ID 中的数字。
示例:我有
ID PN1 PN2
1 2 5
2 3 4
4 6 2
5 2 7
我需要
ID PN1 PN2
1 2 5
2 NA 4
4 NA 2
5 2 NA
如果有人能提供帮助那就太好了!非常感谢您。
library(tidyverse)
df %>%
mutate(across(-ID, ~if_else(. %in% ID, ., NA_real_)))
给出:
# ID PN1 PN2
# 1 1 2 5
# 2 2 NA 4
# 3 4 NA 2
# 4 5 2 NA
使用的数据:
df <- data.frame(ID = c(1, 2, 4, 5),
PN1 = c(2, 3, 6, 2),
PN2 = c(5, 4, 2, 7))
这是基本的 R 方式。
lapply
在除 id 列之外的所有列上循环,使用函数 is.na<-
将 NA
值分配给不在 df1[[1]]
中的向量元素。然后returns改变后的向量。
df1[-1] <- lapply(df1[-1], function(x){
is.na(x) <- !x %in% df1[[1]]
x
})
df1
# ID PN1 PN2
#1 1 2 5
#2 2 NA 4
#3 4 NA 2
#4 5 2 NA
dput
格式的数据
df1 <-
structure(list(ID = c(1L, 2L, 4L, 5L),
PN1 = c(2L, NA, NA, 2L), PN2 = c(5L, 4L, 2L, NA)),
row.names = c(NA, -4L), class = "data.frame")
我们可以使用 mutate
和 case_when
:
library(dplyr)
df %>%
mutate(across(starts_with("PN"), ~case_when(!(. %in% ID) ~ NA_real_,
TRUE ~ as.numeric(.))))
输出:
# A tibble: 4 x 3
ID PN1 PN2
<int> <dbl> <dbl>
1 1 2 5
2 2 NA 4
3 4 NA 2
4 5 2 NA
使用 data.table 您可以 (l) 将函数 fifelse()
应用于每一列
您选择了 .SD
& .SDcols
.
require(data.table)
cols = grep('PN', names(df)) # column indices (or names)
df[ , lapply(.SD, function(x) fifelse(!x %in% ID, NA_real_, x)),
.SDcols = cols ]
来自@deschen 的数据:
df = data.frame(ID = c(1, 2, 4, 5),
PN1 = c(2, 3, 6, 2),
PN2 = c(5, 4, 2, 7))
setDT(df)
Base R
、
的替代方案
df[,-1][matrix(!(unlist(df[,-1]) %in% df[,1]),nrow(df))] <- NA
df
给予,
ID PN1 PN2
1 1 2 5
2 2 NA 4
3 4 NA 2
4 5 2 NA
我有一个数据集,其中一个变量带有参与者 ID,多个变量带有同行提名(以 ID 的形式)。
我需要用 NA 替换同行提名变量中所有不在参与者 ID 中的数字。
示例:我有
ID PN1 PN2
1 2 5
2 3 4
4 6 2
5 2 7
我需要
ID PN1 PN2
1 2 5
2 NA 4
4 NA 2
5 2 NA
如果有人能提供帮助那就太好了!非常感谢您。
library(tidyverse)
df %>%
mutate(across(-ID, ~if_else(. %in% ID, ., NA_real_)))
给出:
# ID PN1 PN2
# 1 1 2 5
# 2 2 NA 4
# 3 4 NA 2
# 4 5 2 NA
使用的数据:
df <- data.frame(ID = c(1, 2, 4, 5),
PN1 = c(2, 3, 6, 2),
PN2 = c(5, 4, 2, 7))
这是基本的 R 方式。
lapply
在除 id 列之外的所有列上循环,使用函数 is.na<-
将 NA
值分配给不在 df1[[1]]
中的向量元素。然后returns改变后的向量。
df1[-1] <- lapply(df1[-1], function(x){
is.na(x) <- !x %in% df1[[1]]
x
})
df1
# ID PN1 PN2
#1 1 2 5
#2 2 NA 4
#3 4 NA 2
#4 5 2 NA
dput
格式的数据
df1 <-
structure(list(ID = c(1L, 2L, 4L, 5L),
PN1 = c(2L, NA, NA, 2L), PN2 = c(5L, 4L, 2L, NA)),
row.names = c(NA, -4L), class = "data.frame")
我们可以使用 mutate
和 case_when
:
library(dplyr)
df %>%
mutate(across(starts_with("PN"), ~case_when(!(. %in% ID) ~ NA_real_,
TRUE ~ as.numeric(.))))
输出:
# A tibble: 4 x 3
ID PN1 PN2
<int> <dbl> <dbl>
1 1 2 5
2 2 NA 4
3 4 NA 2
4 5 2 NA
使用 data.table 您可以 (l) 将函数 fifelse()
应用于每一列
您选择了 .SD
& .SDcols
.
require(data.table)
cols = grep('PN', names(df)) # column indices (or names)
df[ , lapply(.SD, function(x) fifelse(!x %in% ID, NA_real_, x)),
.SDcols = cols ]
来自@deschen 的数据:
df = data.frame(ID = c(1, 2, 4, 5),
PN1 = c(2, 3, 6, 2),
PN2 = c(5, 4, 2, 7))
setDT(df)
Base R
、
df[,-1][matrix(!(unlist(df[,-1]) %in% df[,1]),nrow(df))] <- NA
df
给予,
ID PN1 PN2
1 1 2 5
2 2 NA 4
3 4 NA 2
4 5 2 NA