mle
mle

Reputation: 21

Comparing variables with values in another dataframe and replace them with another value

I have a Data.Frame with:

Height <- c(169,176,173,172,176,158,168,162,178)

and another with reference heights and weights.

heights_f <- c(144.8,147.3,149.9,152.4,154.9,157.5,160,162.6,165.1,167.6,170.2,172.7,175.3,177.8,180.3,182.9,185.4,188,190.5,193,195.6)
weights_f <- c(38.6,40.9,43.1,45.4,47.7,49.9,52.2,54.5,56.8,59,61.3,63.6,65.8,68.1,70.4,72.6,74.9,77.2,79.5,81.7,84)
weightfactor_f <- data.frame(heights_f, weights_f)

I now need to match the values of the heights from the first data.frame with the height reference in the second one that's the most fitting and to give me the correspondent reference weight.

I haven't yet had any success, as I haven't been able to find anything about matching values that are not exactly the same.

Upvotes: 1

Views: 86

Answers (4)

Odysseus210
Odysseus210

Reputation: 468

library(dplyr)

Slightly different structure to reproducible example:

Height <- data.frame(height = as.numeric(c(169,176,173,172,176,158,168,162,178)))

The rest is the same:

heights_f<- as.numeric(c(144.8,147.3,149.9,152.4,154.9,157.5,160,162.6,165.1,167.6,170.2,172.7,175.3,177.8,180.3,182.9,185.4,188,190.5,193,195.6)) 
weights_f<- as.numeric(c(38.6,40.9,43.1,45.4,47.7,49.9,52.2,54.5,56.8,59,61.3,63.6,65.8,68.1,70.4,72.6,74.9,77.2,79.5,81.7,84)) 
weightfactor_f<- data.frame(heights_f,weights_f)

Then, round to the nearest whole number:

weightfactor_f$heights_f <- round(weightfactor_f$heights_f, 0)

Then just:

left_join(Height, weightfactor_f, by = c("height" = "heights_f"))

Output:

  height weights_f
1    169        NA
2    176        NA
3    173      63.6
4    172        NA
5    176        NA
6    158      49.9
7    168      59.0
8    162        NA
9    178      68.1

Upvotes: 0

nicola
nicola

Reputation: 24480

If I understand your goal, instead of taking the nearest value, consider interpolating through the approx function. For instance:

approx(weightfactor_f$heights_f,weightfactor_f$weights_f,xout=Height)$y
#[1] 60.23846 66.44400 63.85385 62.95600 66.44400 50.36000 59.35385 53.96923
#[9] 68.28400

Upvotes: 5

Kalees Waran
Kalees Waran

Reputation: 659

z <- vector()
for(i in 1:length(Height)) {
z[i] <- weightfactor_f$weights_f[which.min(abs(Height[i]-weightfactor_f$heights_f))]
}

Upvotes: -1

Florian
Florian

Reputation: 25385

You could do:

Height<- c(169,176,173,172,176,158,168,162,178)
heights_f<- as.numeric(c(144.8,147.3,149.9,152.4,154.9,157.5,160,162.6,165.1,167.6,170.2,172.7,175.3,177.8,180.3,182.9,185.4,188,190.5,193,195.6)) 
weights_f<- as.numeric(c(38.6,40.9,43.1,45.4,47.7,49.9,52.2,54.5,56.8,59,61.3,63.6,65.8,68.1,70.4,72.6,74.9,77.2,79.5,81.7,84)) 

df = data.frame(Height=Height, match_weight=
          sapply(Height, function(x) {weights_f[which.min(abs(heights_f-x))]}))

i.e. for each entry in Height, find the corresponding element in the heights_f vector by doing which.min(abs(heights_f-x) and fetch the corresponding entry from the weights_f vector.


Output:

  Height match_weight
1    169         61.3
2    176         65.8
3    173         63.6
4    172         63.6
5    176         65.8
6    158         49.9
7    168         59.0
8    162         54.5
9    178         68.1

Upvotes: 0

Related Questions