2

I have a data frame:

df <- data.frame(A=c(10, 20, 30, 20), 
      B=c(0, 10, 20, 10), 
      C=c(11, 22, 21, 12),
      D=c(13, 11, 33, 15))

 A  B  C  D
10  0 11 13
20 10 22 11
30 20 21 33
20 10 12 15

and a function to get the index of the number in a pair closest to a number of interest:

comp <- function(x, y) {
    # x = number of interest, y = vector of 2 numbers for comparison)
    ind <- which(abs(y-x)==min(abs(y-x)))
    if (length(ind)==2) {
        ind <- 3
    }
    return(ind)
}

(The if statement is for when the number is smack in the middle of the two numbers, ex. 15 compared to 10 and 20).

I would like to change columns C & D to the index for which the number is closest using my function (1 for A or 2 for B):

 A  B  C  D
10  0  1  1
20 10  1  2
30 20  2  1
20 10  2  3

I'm not sure how to call in columns A and B as arguments for the function. I've tried mutate_at(df, 3:4, funs(comp), c(df$A, df$B)), but that returns:

 A  B C D
10  0 3 6
20 10 3 6
30 20 3 6
20 10 3 6

Doesn't have to be a tidyr solution, whatever works! Thanks

2
  • Your function only takes two arguments. What should x and y be? A and B, or A & C and B & C, etc? Commented Jul 5, 2018 at 19:05
  • x is the number of interest, y is a vector of 2 numbers. Ex. comp(13, c(10, 20)) returns 1, since that is the index of the closest number in the pair. So for the df, c(df$A, df$B) is my attempt at calling the y argument, since the x argument should be an individual column (C or D). Commented Jul 5, 2018 at 19:07

1 Answer 1

2

I changed around your function a little bit in order for vectorization to work. It also only accepted 2 values, when you were looking to compare 1 value with 2 others, so 3 arguments would be needed:

comp <- function(val, x, y){
  case_when(
    abs(val - x) < abs(val - y) ~ 1,
    abs(val - x) > abs(val - y) ~ 2,
    TRUE ~ 3)
}

df %>% 
  mutate_at(vars(C,D), comp , .$A, .$B)

   A  B C D
1 10  0 1 1
2 20 10 1 2
3 30 20 2 1
4 20 10 2 3
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect, thanks for the introduction to case_when!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.