Reputation: 137
I created a function where R looks at many variables, then it populates a new column in such way:
-if any of the variables has a "1" entry, the new column should be a "1"
-if they are all variables have NA entries, the new column should have an NA value.
This should be very simple, yet it somehow does not work. I think the issue is in the part of the code where I check it they all are not NA values: "if(!((is.na(variable))|..."
Any idea of a better way to code this? Please help!
Note: there are many more calculations done inside this function but for the purpose of showing the function structure and my specific issue I have only left this part inside it.
#if they answered "1" (yes) to recieving any specific treatment,
#then say "1" (yes) to a new columns called treated_psych
diag_treated <- function(x){
for (v in 1:length(x)) assign(names(x)[v], x[[v]])
if(!((is.na(CurrTx6.1_Group))|(is.na(CurrTx6.1_Ind))| (is.na(CurrTx6.1_Fam))|
(is.na(CurrTx6.1_Couples))|(is.na(CurrTx7a_CBTAnx))|(is.na(CurrTx7b_CBTDep))|
(is.na(CurrTx7c_CBTInsom)))){
if(CurrTx6.1_Group==1 | CurrTx6.1_Ind==1 | CurrTx6.1_Fam==1 | CurrTx6.1_Couples==1 |
CurrTx7a_CBTAnx==1 | CurrTx7b_CBTDep==1 | CurrTx7c_CBTInsom==1)
{
treated_psych <-1
}
else{treated_psych <- 0}
}else{treated_psych<-NA}
treat <- data.frame(treated_psych)
return(treat)
}
#call function
diagnoses_treated <- adply(dataset, 1, diag_treated)
Upvotes: 0
Views: 97
Reputation: 137
I ended up doing a subset of the columns, 2 apply funcitons and then a for loop that goes through both vectors created from apply function to make my new variable. Not very elegant or efficient but it works.
#if they answered "1" (yes) to recieving any specific treatment,
#then say "1" (yes) to a new columns called treated_psych
#subset data by just these columns
df_psych<- dat_with_pcl5[c("CurrTx6.1_Group", "CurrTx6.1_Ind", "CurrTx6.1_Fam",
"CurrTx6.1_Couples", "CurrTx7a_CBTAnx", "CurrTx7b_CBTDep", "CurrTx7c_CBTInsom")]
#make one vector if ANY are 1, make another vector if ALL are NA
treated_psych1<- apply(df_psych, 1, function(r) any(r %in% "1"))
treated_psych.na<- apply(df_psych, 1, function(r) all(r %in% NA))
# Loop through both vectors and create new variable
#if true treated_psych1 then 1, if true in treated_psych.na then NA
for(i in 1:length(treated_psych0)){
if (treated_psych1[i]==TRUE){treated_psych[i] <- 1}
if (treated_psych.na[i] ==TRUE){treated_psych[i] <- NA}
}
Upvotes: 0
Reputation: 158
I generated this sample data based on how you've described the data. If this is not correct, please provide reproducible sample data.
sample_data=data.frame("CurrTx6.1_Group"=c(1,1,0,0,NA),
"CurrTx6.1_Fam"=c(NA,NA,0,0,NA),
"CurrTx7b_CBTDep"=c(1,1,0,1,NA))
sample_data
new_var<-rep("xxx",nrow(sample_data)) #Initialize new column variable
for(i in 1:nrow(sample_data)){
if(all(is.na(sample_data[i,]))){
new_var[i]=NA #If any elements in the row are NA, mark the new variable NA
}
}
not_na_index=which(!is.na(new_var)) #Find places where the new value will be 0 or 1
new_var[not_na_index]=rowSums(sample_data, na.rm = TRUE)[not_na_index] #Sum the rows, since everything that is 0 should stay 0, and a single 1 will make the final variable a 1
new_var<-as.numeric(new_var) #Change to numeric (was initialized as string)
new_var[which(new_var>1)]=1 #Change any number higher than 1 to 1
sample_data$new_column=new_var
sample_data
The new variable returned is 1 1 0 1 NA
Upvotes: 1