2

I have two variables transID and transid

transID        transid
fsdfsdgls         NA
dfdsfgdsgs     mksdjfl
werwer         fgsdsdg
xcvcxvx           NA

I want the output like

transID         transid
fsdfsdgls          NA 
mksdjfl         mksdjfl 
fgsdsdg         fgsdsdg
xcvcxvx           NA

I want to replace the value in transID with transid when it is not NA

MrFlick
  • 195,160
  • 17
  • 277
  • 295
63549
  • 95
  • 1
  • 5
  • Some form of a [coalesce](http://stackoverflow.com/questions/19253820/how-to-implement-coalesce-efficiently-in-r) function may be useful for returning the first non-NA value. – MrFlick May 11 '16 at 04:26

2 Answers2

2

Since there are only two choices, you can use a single ifelse():

df <- data.frame(transID=c('fsdfsdgls','dfdsfgdsgs','werwer','xcvcxvx'),transid=c(NA,'mksdjfl','fgsdsdg',NA),stringsAsFactors=F);
df$transID <- ifelse(is.na(df$transid),df$transID,df$transid);
df;
##     transID transid
## 1 fsdfsdgls    <NA>
## 2   mksdjfl mksdjfl
## 3   fgsdsdg fgsdsdg
## 4   xcvcxvx    <NA>

Another possibility, by precomputing which indexes require replacement:

i <- which(!is.na(df$transid));
df$transID[i] <- df$transid[i];
df;
##     transID transid
## 1 fsdfsdgls    <NA>
## 2   mksdjfl mksdjfl
## 3   fgsdsdg fgsdsdg
## 4   xcvcxvx    <NA>
bgoldst
  • 34,190
  • 6
  • 38
  • 64
  • I tried using the above code in dataset.It showing an error Error in ifelse(is.na(la2$transid), la2$transID, la2$transid) : replacement has length zero In addition: Warning message: In rep(yes, length.out = length(ans)) : 'x' is NULL so the result will be NULL – 63549 May 11 '16 at 04:38
1

We can use data.table to do this in a faster way as the := does this in place. Convert the 'data.frame' to 'data.table' (setDT(df)), specify the logical condition in 'i' (!is.na(transid)) and assign (:=) 'transid' values corresponding to the TRUE values in 'i' to 'transID' column.

library(data.table)
setDT(df)[!is.na(transid), transID := transid]
df
#     transID transid
#1: fsdfsdgls      NA
#2:   mksdjfl mksdjfl
#3:   fgsdsdg fgsdsdg
#4:   xcvcxvx      NA

data

df <- structure(list(transID = c("fsdfsdgls", "dfdsfgdsgs", "werwer", 
"xcvcxvx"), transid = c(NA, "mksdjfl", "fgsdsdg", NA)),
.Names = c("transID", "transid"), class = "data.frame",
row.names = c(NA, -4L))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I tried this setDT(la2)[!is.na(la2$transid), la2$transId := la2$transid] Error in `[.data.table`(setDT(la2), !is.na(la2$transid), `:=`(la2$transId, : LHS of := isn't column names ('character') or positions ('integer' or 'numeric') – 63549 May 11 '16 at 04:55
  • @63549 Updated with the data I used. Do you have `factor` columns? I used `character` columns. If they are `factor` columns, convert to `character` i.e. `df[] <- lapply(df, as.character)` and then apply the code – akrun May 11 '16 at 05:01