Reputation: 1163
I have several pairs of variables e.g. X1 and Y1, X2 and Y2...Xn and Yn etc). I know hoe to obtain the minimum value of some of the columns e.g (X1, X2...Xn), but I would like to find the Y value that corresponds to the minimum X value. I was thinking potentially some sort of key/value pair... would do the trick, but cant quite figure out how to implement it. If someone could help with any form of a solution, that would be fantastic.
# Make some dummy data
X1 = c(1,20,3,40,5)
Y1 = c(20,32,60,82,100)
X2 = c(10,2,30,4,50)
Y2= c(2,30,6,80,10)
df = data.frame(X1,Y1,X2,Y2)
# This is what the dataframe looks like
X1 Y1 X2 Y2
1 1 20 10 2
2 20 32 2 30
3 3 60 30 6
4 40 82 4 80
5 5 100 50 10
# create column of minimum X values
df$minX = c(pmin( df[,1], df[,3]))
I want to create another column with the Y value corresponding to the minimum value of X, but cant quite figure out how to do it. In the example above, the resultant dataframe should look something like the following. NOTE : The corresponding Y value is not necessarily max or min).
X1 Y1 X2 Y2 minX correspondingY
1 1 20 10 2 1 20
2 20 32 2 30 2 30
3 3 60 30 6 3 60
4 40 82 4 80 4 80
5 5 100 50 10 5 100
Any help would be appreciated. Thanks in advance.
Upvotes: 1
Views: 1280
Reputation: 388797
In tidyverse
you can do :
library(dplyr)
df1 <- df %>% mutate(row = row_number())
df1 %>%
inner_join(
df1 %>%
tidyr::pivot_longer(cols = -row,
names_to = c('.value'),
names_pattern = '([A-Z])') %>%
group_by(row) %>%
slice(which.min(X)), by = 'row')
# X1 Y1 X2 Y2 row X Y
#1 1 20 10 2 1 1 20
#2 20 32 2 30 2 2 30
#3 3 60 30 6 3 3 60
#4 40 82 4 80 4 4 80
#5 5 100 50 10 5 5 100
You can remove the row
column if it is not needed.
Upvotes: 1
Reputation: 101034
Maybe you can try the code below
X <- df[startsWith(names(df), "X")]
df$minX <- do.call(pmin, X)
df$correspondingY <- df[startsWith(names(df), "Y")][cbind(seq(nrow(X)), max.col(-X))]
which gives
> df
X1 Y1 X2 Y2 minX correspondingY
1 1 20 10 2 1 20
2 20 32 2 30 2 30
3 3 60 30 6 3 60
4 40 82 4 80 4 80
5 5 100 50 10 5 100
Upvotes: 1