Dear List,
I am trying to take the weighted average of two numbers (visual acuity
measures from the left and right eye). For each row, the lowest value
should get a weight of .75, and the highest a weight of .25. My
problem is, if one value is missing (NA), the remaining one should get
a weight of 1 (i.e., just return the nonmissing value), if both are
missing, NA should be returned. Below is some example data and the
code I tried to write (Desired is what I actually want). Any thoughts
or comments would be welcome.
Thanks,
Josh
VA <- cbind(OS = c(.2, 0, 1, -.1, NA, 3, NA),
OD = c(.3, -.1, .2, -.1, NA, 0, .1),
Desired = c(0.225, -0.075, 0.4, -0.1, NA, 0.75, 0.1))
## What I tried
weight.combine <- function(left, right) {
out.r <- right
out.l <- left
right <- ifelse(out.r <= out.l, out.r * .75, out.r * .25)
left <- ifelse(out.r > out.l, out.l * .75, out.l * .25)
rowSums(cbind(left, right), na.rm = TRUE)
}
## This "works", except it does not handle NAs properly
weight.combine(VA[, "OS"], VA[, "OD"])
--
Joshua Wiley
Ph.D. Student, Health Psychology
University of California, Los Angeles
http://www.joshuawiley.com/
On Apr 2, 2011, at 10:20 PM, Joshua Wiley wrote:> Dear List, > > > I am trying to take the weighted average of two numbers (visual acuity > measures from the left and right eye). For each row, the lowest value > should get a weight of .75, and the highest a weight of .25. My > problem is, if one value is missing (NA), the remaining one should get > a weight of 1 (i.e., just return the nonmissing value), if both are > missing, NA should be returned. Below is some example data and the > code I tried to write (Desired is what I actually want). Any thoughts > or comments would be welcome. > > Thanks, > > Josh > > > VA <- cbind(OS = c(.2, 0, 1, -.1, NA, 3, NA), > OD = c(.3, -.1, .2, -.1, NA, 0, .1), > Desired = c(0.225, -0.075, 0.4, -0.1, NA, 0.75, 0.1)) > > ## What I tried > weight.combine <- function(left, right) { > out.r <- right > out.l <- left > right <- ifelse(out.r <= out.l, out.r * .75, out.r * .25) > left <- ifelse(out.r > out.l, out.l * .75, out.l * .25) > rowSums(cbind(left, right), na.rm = TRUE) > } >VA <- cbind(VA, 0.75*pmin(VA[, "OS"], VA[, "OD"], na.rm=TRUE) + 0.25*pmax(VA[, "OS"], VA[, "OD"], na.rm=TRUE) ) > VA OS OD Desired [1,] 0.2 0.3 0.225 0.225 [2,] 0.0 -0.1 -0.075 -0.075 [3,] 1.0 0.2 0.400 0.400 [4,] -0.1 -0.1 -0.100 -0.100 [5,] NA NA NA NA [6,] 3.0 0.0 0.750 0.750 [7,] NA 0.1 0.100 0.100> ## This "works", except it does not handle NAs properly > weight.combine(VA[, "OS"], VA[, "OD"]) > > > -- > Joshua WileyDavid Winsemius, MD West Hartford, CT
On Sat, Apr 2, 2011 at 7:59 PM, David Winsemius <dwinsemius at comcast.net> wrote:> > On Apr 2, 2011, at 10:20 PM, Joshua Wiley wrote: >> VA <- cbind(OS = c(.2, 0, 1, -.1, NA, 3, NA), >> ?OD = c(.3, -.1, .2, -.1, NA, 0, .1), >> ?Desired = c(0.225, -0.075, 0.4, -0.1, NA, 0.75, 0.1)) > > ?VA <- cbind(VA, 0.75*pmin(VA[, "OS"], VA[, "OD"], na.rm=TRUE) + > ? ? ? ? ? ? ? ? ?0.25*pmax(VA[, "OS"], VA[, "OD"], na.rm=TRUE) ) > >> VA > ? ? ? OS ? OD Desired > [1,] ?0.2 ?0.3 ? 0.225 ?0.225 > [2,] ?0.0 -0.1 ?-0.075 -0.075 > [3,] ?1.0 ?0.2 ? 0.400 ?0.400 > [4,] -0.1 -0.1 ?-0.100 -0.100 > [5,] ? NA ? NA ? ? ?NA ? ? NA > [6,] ?3.0 ?0.0 ? 0.750 ?0.750 > [7,] ? NA ?0.1 ? 0.100 ?0.100 >That works wonderfully, and it is so elegant! Thank you, David. Josh> > David Winsemius, MD > West Hartford, CT >