问题描述
我有一个包含数十列和几千行的数据框。我想以8变为NA的方式重新编码最大值为8的数字列,并以8变为NA且9变为9999的方式重新编码最大值为9的数字列。例如,
mydf <- data.frame(a = c(1,2,8,9),b = c(7,9,10),c = c(4,5,6,d = c(5,7,8),e = c("a","b","c","d"))
> mydf
a b c d e
1 1 7 4 5 a
2 2 8 5 6 b
3 8 9 6 7 c
4 9 10 9 8 d
将成为:
> mydf
a b c d e
1 1 7 4 5 a
2 2 8 5 6 b
3 NA 9 6 7 c
4 9999 10 9999 NA d
我想这样做:
mydf1 <- mydf[,sapply(mydf,max) == 8]
mydf2 <- mydf[,max) == 9]
mydf1[mydf1 == 8] <- NA
mydf2[mydf2 == 8] <- NA
mydf2[mydf2 == 9] <- 9999
但是我不知道如何将新数据帧中的重新编码的变量带回到原始数据帧中,而且我敢肯定还有更有效的解决方案。
解决方法
您可以使用max
检查每一列的lapply
值,并重新编码是8还是9。
mydf[] <- lapply(mydf,function(x) {
if(max(x) %in% c(8,9)) {
x[x == 8] <- NA
x[x == 9] <- 9999
}
x
})
mydf
# a b c d e
#1 1 7 4 5 a
#2 2 8 5 6 b
#3 NA 9 6 7 c
#4 9999 10 9999 NA d
,
我们可以使用tidyverse
方法动态检查该列是否为数字,然后循环across
这些列,检查8或9是否为%in%
的值max
,然后使用na_if
将8替换为NA,然后使用replace
将9替换为9999
library(dplyr)
mydf %>%
mutate(across(where(is.numeric),~
if(any(c(8,9) %in% max(.,na.rm = TRUE))) replace(na_if(.,8),.==9,9999)))
# a c d e
#1 1 4 5 a
#2 2 5 6 b
#3 NA 6 7 c
#4 9999 9999 NA d