Correct values of data-frame rows based on reference row

Viewed 34

I have a large data frame with K columns, where in unknown column indices I have the character "X" in it. I wish to replace be some value based on the reference row with K columns as well.

I can do it using for loop easily:

ref_r = mu_df[1, ]
for (n in row.names(mu_df)) {
    idx = which(mu_df[n, ] == "X")
    mu_df[n, idx] = ref_r[idx]
}

The above code finds the indices where "X" appears and replaces them in the values in the same position from the ref_row.

I wish to optimize it, I was thinking of using 1 of the apply family but I couldn't improve by anything.

An example is:

mu_df = data.frame(c1=c("A", "-", "X", "-", "B"), c2=c("I", "G", "R", "X", "S"), c3=c("-", "K", "-", "-", "B"), c4=c("Q", "-", "L", "-", "X"), row.names = c("t1", "t2", "t3", "t4", "t5"))

And the expected output is:

   c1 c2 c3 c4
t1  A  I  -  Q
t2  -  G  K  -
t3  A  R  -  L
t4  -  I  -  -
t5  B  S  B  Q

How can I optimize it, as I have to process thousands of such data-frames in that manner?

Would appreciate some help.

1 Answers

We can use which with arr.ind = TRUE to get row/column index of each value of 'X'.

ref_r <- unlist(mu_df[1, ])
mat <- which(mu_df == 'X', arr.ind = TRUE)
mu_df[mat] <- ref_r[mat[, 2]]

#   c1 c2 c3 c4
#t1  A  I  -  Q
#t2  -  G  K  -
#t3  A  R  -  L
#t4  -  I  -  -
#t5  B  S  B  Q
Related