Jørgen K. Kanters
Jørgen K. Kanters

Reputation: 868

How to workaround NAs in subscripted assignments

I have some data with a representative subpart here

id     visitdate   ecgday
5130   1999-09-22  1999-09-22
6618   NA          1999-12-01 
10728  2000-06-27  2000-06-27
968    1999-04-19  1999-04-19
5729   1999-09-23  NA
1946   NA          NA
15070  1999-11-09  NA

What I want is to create a novel variable visitday which is equal to ecgday, unless ecgday is NA. In that case it should be visitday -> visitdate unless both visitdate and ecgday are NA, where visitday should be NA.

I have tried

int99$visitday <- int99$visitdate    
int99$visitday[!is.na(int99$ecgday) & int99$ecgday > int99$visitdate]   
     <-int99$ecgday[!is.na(int99$ecgday) & int99$ecgday > int99$visitdate]

but it gave the error:

Error in [.data.frame(int99, , c("id", "visitday", "visitdate", : undefined columns selected

which I understand. Any workaround to get the desired result?

Upvotes: 1

Views: 295

Answers (3)

J&#248;rgen K. Kanters
J&#248;rgen K. Kanters

Reputation: 868

Thanks to Derek Corcoran

That worked except for a very small thing that visitday ended up being numeric despite both ecgday and visitdate being Date.

That was easy fixed by adding a line

int99$visitday <- ifelse(is.na(int99$ecgday), int99$visitdate , int99$ecgday)
int99$visitday <- ifelse(is.na(int99$visitdate), int99$ecgday , int99$visitdate)
int99$visitday <- as.Date(int99$visitday, origin="1970-01-01")

Thank You so much.

Upvotes: 1

R.S.
R.S.

Reputation: 2140

In my view the best way to deal with such NA comparison it to change dates to numeric and all NAs to 0. Though quite possibly I did not understand the question correctly, in case you want to set the new variable to the higher of the visitdate and ecgday, you can try this. Or it can be adapted to any other requirement

int99<- read.table(header = T, colClasses = c("numeric", "Date","Date"),
text="id visitdate ecgday
5130 1999-09-22 1999-09-22
6618 NA 1999-12-01 
10728 2000-06-27 2000-06-27
968 1999-04-19 1999-04-19
5729 1999-09-23 NA
1946 NA NA
15070 1999-11-09 NA" )

dt<- apply(int99[,2:3], 2 , zoo::as.Date)
dt  
dt[is.na(dt)]<- 0
dt  
mx<- apply(dt,1,max)

mx[mx==0]<- NA

int99$visitday<- zoo::as.Date(mx)

int99

Upvotes: 0

Derek Corcoran
Derek Corcoran

Reputation: 4082

this Should do it:

First if ecday is NA it will be visitday, if not it will be ecgday

int99$visitday <- felse(is.na(int99$ecgday), int99$visitdate , int99$ecgday)

for cases when both have NAs, you can add a next ifelse:

int99$visitday <- ifelse(is.na(int99$visitdate), int99$ecgday , int99$visitdate)

Upvotes: 3

Related Questions