Reputation: 295
I have problem with my code. I have data frame like this:
A <- c(21, 234, NA, 286,NA)
B <- c(3,NA,NA, 8, 10)
data <- data.frame(A,B)
data
A B
1 21 3
2 234 NA
3 NA NA
4 286 8
5 NA 10
And the effect I want to create is:
A B A_NA B_NA
1 21 3 0 0
2 234 NA 0 1
3 NA NA 1 1
4 286 8 0 0
5 NA 10 1 0
Here is my simple code, but something doesn't work..
for(i in c(1:ncol(data)))
{
data[, ncol(data) + 1] <- ifelse(is.na(data[i]), 1, 0)
names(data)[ncol(data)] <- paste0(colnames(data[i]), "_NA")
}
because effect is:
A B A A B A A
1 21 3 0 0 0 0 0
2 234 NA 0 0 1 0 0
3 NA NA 1 1 1 0 0
4 286 8 0 0 0 0 0
5 NA 10 1 1 0 0 0
Upvotes: 1
Views: 2005
Reputation: 1795
Adding columns based on a condition:
data$A_NA<-ifelse(is.na(data$A),1,0)
data$B_NA<-ifelse(is.na(data$B),1,0)
Recursively:
for(nm in names(data))
eval(parse(text = paste0("data$",nm,"_NA<-ifelse(is.na(data$",nm,"),1,0)")))
Alternatively one can use:
for(nm in names(data)){
assign(paste0(nm,"_NA"), ifelse(is.na(data[nm]),1,0))
tempo<-data.frame(get(paste0(nm,"_NA")));names(tempo)<-paste0(nm,"_NA")
data<-cbind(data,tempo)
}
Upvotes: 0
Reputation: 886938
We can use lapply
to loop over the columns of 'data', check whether the elements are NA (is.na(x)
), convert to integer (as.integer
) and assign the output to new columns
data[paste0(names(data), "_NA")] <- lapply(data, function(x) as.integer(is.na(x)))
data
# A B A_NA B_NA
#1 21 3 0 0
#2 234 NA 0 1
#3 NA NA 1 1
#4 286 8 0 0
#5 NA 10 1 0
Upvotes: 2