我正在使用具有相似结构但值不同的3个数据帧。我想根据要转换的变量中的条件和数据集中的第二个变量来转换/变换特定变量。数据集中的其他变量应保持不变。
在我的示例数据中,我想将列VAR1-3转换为NA IF,相应的AGE< 65 AND如果它自己的列具有值0.
foo <- data.frame('AGE'=c(50,65,66,40,70,25,65,67,44,56), 'SMOKING'=c(0,0,0,0,0,1,1,1,1,1),
'VAR1'=c(1,0,0,1,0,1,0,1,0,0),'VAR2'=c(0,0,1,0,0,1,0,0,0,1),'VAR3'=c(1,0,1,1,1,0,0,0,1,0))
VARv <- c('VAR1','VAR2','VAR3')
OTHERSv <- c('SMOKING')
AGEVARv <- c('AGE', VARv)
由于我的数据集很大(> 2000变量)且变量的顺序可能不同,我想使用保存在向量中的变量名。
我可以使用以下for循环执行此操作,但想学习如何使用dplyr或应用函数
for (i in 1: length(VARv)) {foo[,VARv[i]] <- replace(foo[VARv[i]], foo[VARv[i]]==0 & foo$AGE<65, NA)}
如果我在数据集中没有二进制变量SMOKING,我可以
foo <- apply(foo, 2,function(y) {
foo[foo==0 & foo$AGE < 65] <- NA
return(foo)
})
但这也会改变SMOKING变量。
问题:如果其中一个我想通过名称引用我想要自动处理的其他人,如何选择和引用应用函数中的变量?
我有这样的想法,但我如何正确引用变量AGE?此尝试生成具有正确NA操作的21列数据,但重复每列的所有列(AGE.SMOKING,AGE.AGE,AGE.VAR1 ...,VAR1.SMOKING,VAR1.AGE,VAR1.VAR1 ETC)
b <- data.frame(foo[colnames(foo) %in% OTHERSv], apply(foo[colnames(foo) %in% AGEVARv],2,function(y) {
foo[foo==0 & foo$AGE < 65] <- NA
return(foo)
}))
我很感激任何见解!
答案 0 :(得分:1)
我们可以创建一个重用函数
library(dplyr)
f1 <- function(dat, varCols, AgeCol){
Age <- rlang::sym(AgeCol)
dat %>%
mutate_at(vars(varCols), funs(replace(., .==0 & (!!Age) < 65, NA)))
}
AgeC <- 'AGE'
f1(foo, VARv, AgeC)
# AGE SMOKING VAR1 VAR2 VAR3
#1 50 0 1 NA 1
#2 65 0 0 0 0
#3 66 0 0 1 1
#4 40 0 1 NA 1
#5 70 0 0 0 1
#6 25 1 1 1 NA
#7 65 1 0 0 0
#8 67 1 1 0 0
#9 44 1 NA NA 1
#10 56 1 NA 1 NA
我们也可以使用base R
方法
f2 <- function(dat, varCols, AgeCol){
dat[varCols] <- (NA^(dat[[AgeCol]] < 65 & !dat[varCols]))*dat[varCols]
dat
}
all.equal(f1(foo, VARv, AgeC), f2(foo, VARv, AgeC), check.attributes = FALSE)
#[1] TRUE
答案 1 :(得分:1)
您可以考虑使用case_when()
。
在我的示例数据中,我想将列VAR1-3转换为NA IF 相应的AGE&lt; 65 AND如果它自己的列具有值0.
以下是case_when()
解决此问题的示例:
library(tidyverse)
foo %>%
as_tibble() %>%
mutate(VAR1 = case_when(AGE < 65 & VAR1 == 0 ~ "NA",
TRUE ~ as.character(.$VAR1)),
VAR2 = case_when(AGE < 65 & VAR2 == 0 ~ "NA",
TRUE ~ as.character(.$VAR2)),
VAR3 = case_when(AGE < 65 & VAR3 == 0 ~ "NA",
TRUE ~ as.character(.$VAR3)))
返回:
# A tibble: 10 x 5
AGE SMOKING VAR1 VAR2 VAR3
<dbl> <dbl> <chr> <chr> <chr>
1 50 0 1 NA 1
2 65 0 0 0 0
3 66 0 0 1 1
4 40 0 1 NA 1
5 70 0 0 0 1
6 25 1 1 1 NA
7 65 1 0 0 0
8 67 1 1 0 0
9 44 1 NA NA 1
10 56 1 NA 1 NA