Closest value to a specific column in R
I would like to find the closest value to column x3 below.
data=data.frame(x1=c(24,12,76),x2=c(15,30,20),x3=c(45,27,15))
data
x1 x2 x3
1 24 15 45
2 12 30 27
3 76 20 15
So desired output will be
Closest_Value_to_x3
24
30
20
Please help. Thank you
r dataframe closest
add a comment |
I would like to find the closest value to column x3 below.
data=data.frame(x1=c(24,12,76),x2=c(15,30,20),x3=c(45,27,15))
data
x1 x2 x3
1 24 15 45
2 12 30 27
3 76 20 15
So desired output will be
Closest_Value_to_x3
24
30
20
Please help. Thank you
r dataframe closest
add a comment |
I would like to find the closest value to column x3 below.
data=data.frame(x1=c(24,12,76),x2=c(15,30,20),x3=c(45,27,15))
data
x1 x2 x3
1 24 15 45
2 12 30 27
3 76 20 15
So desired output will be
Closest_Value_to_x3
24
30
20
Please help. Thank you
r dataframe closest
I would like to find the closest value to column x3 below.
data=data.frame(x1=c(24,12,76),x2=c(15,30,20),x3=c(45,27,15))
data
x1 x2 x3
1 24 15 45
2 12 30 27
3 76 20 15
So desired output will be
Closest_Value_to_x3
24
30
20
Please help. Thank you
r dataframe closest
r dataframe closest
edited Jan 23 at 13:36
markus
14.3k11236
14.3k11236
asked Jan 23 at 13:24
melikmelik
17012
17012
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
Use max.col(-abs(data[, 3] - data[, -3]))
to find the column positions of the closest values and use this result as part of a matrix to extract desired values from your data. The matrix is returned by cbind
col <- 3
data[, -col][cbind(1:nrow(data),
max.col(-abs(data[, col] - data[, -col])))]
#[1] 24 30 20
Nice answer. Although I don't think the outside[, 1:2]
subset is necessary since you've already done that subset inside theabs()
call.
– Rich Scriven
Jan 23 at 20:25
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the[, 2:3]
subset.
– markus
Jan 23 at 20:32
add a comment |
Here is another approach using matrixStats
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
x[matrixStats::rowMins(y) == y]
# [1] 24 30 20
Or in base
using vapply
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
vapply(1:nrow(data),
function(k) x[k,][which.min(y[k,])],
numeric(1))
# [1] 24 30 20
add a comment |
A tidyverse
solution:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
select(val)
val
<dbl>
1 24
2 30
3 20
First, it adds a row ID. Second, it transforms the data from wide to long. Third, it calculates the difference between "x3" and the other variables. Finally, it groups by the row ID and keeps the rows where the absolute difference is the smallest.
Or:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
pull(val)
[1] 24 30 20
Or using an approach originally proposed by @markus (it assumes that your columns are named "x"):
data %>%
mutate(temp = paste0("x", max.col(-abs(.[, -3] - .[, 3])))) %>%
rowwise() %>%
summarise(val = eval(as.symbol(temp)))
val
<dbl>
1 24.
2 30.
3 20.
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest and combines it with "x". Then, it evaluates the combination of x and column index as a variable and returns the appropriate value.
Also borrowing the idea from @markus (not assuming that your columns are named "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest. Second, it returns the column name based on the column index. Finally, it evaluates it as a variable and returns the appropriate value.
Or a variant where you can reference the "x3" variable by its name and not by column index (the basic idea still from @markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
1
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that thetidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)
– tmfmnk
Jan 23 at 14:30
1
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
1
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler singlemutate
:data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result ofmax.col
but otherwise that’s it.
– Konrad Rudolph
Jan 24 at 9:57
1
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be onfortunes
.
– RLave
Jan 24 at 10:56
|
show 3 more comments
Define a function closest_to_3
that operates on a vector and returns the value in the vector that's closest to the third member:
closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]
(The idiom v[-3]
deletes the 3rd member from v
.) Then apply this function to each row of your data frame:
apply(data, 1, closest_to_3)
#[1] 24 30 20
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54328301%2fclosest-value-to-a-specific-column-in-r%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Use max.col(-abs(data[, 3] - data[, -3]))
to find the column positions of the closest values and use this result as part of a matrix to extract desired values from your data. The matrix is returned by cbind
col <- 3
data[, -col][cbind(1:nrow(data),
max.col(-abs(data[, col] - data[, -col])))]
#[1] 24 30 20
Nice answer. Although I don't think the outside[, 1:2]
subset is necessary since you've already done that subset inside theabs()
call.
– Rich Scriven
Jan 23 at 20:25
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the[, 2:3]
subset.
– markus
Jan 23 at 20:32
add a comment |
Use max.col(-abs(data[, 3] - data[, -3]))
to find the column positions of the closest values and use this result as part of a matrix to extract desired values from your data. The matrix is returned by cbind
col <- 3
data[, -col][cbind(1:nrow(data),
max.col(-abs(data[, col] - data[, -col])))]
#[1] 24 30 20
Nice answer. Although I don't think the outside[, 1:2]
subset is necessary since you've already done that subset inside theabs()
call.
– Rich Scriven
Jan 23 at 20:25
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the[, 2:3]
subset.
– markus
Jan 23 at 20:32
add a comment |
Use max.col(-abs(data[, 3] - data[, -3]))
to find the column positions of the closest values and use this result as part of a matrix to extract desired values from your data. The matrix is returned by cbind
col <- 3
data[, -col][cbind(1:nrow(data),
max.col(-abs(data[, col] - data[, -col])))]
#[1] 24 30 20
Use max.col(-abs(data[, 3] - data[, -3]))
to find the column positions of the closest values and use this result as part of a matrix to extract desired values from your data. The matrix is returned by cbind
col <- 3
data[, -col][cbind(1:nrow(data),
max.col(-abs(data[, col] - data[, -col])))]
#[1] 24 30 20
edited Feb 18 at 8:23
answered Jan 23 at 13:30
markusmarkus
14.3k11236
14.3k11236
Nice answer. Although I don't think the outside[, 1:2]
subset is necessary since you've already done that subset inside theabs()
call.
– Rich Scriven
Jan 23 at 20:25
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the[, 2:3]
subset.
– markus
Jan 23 at 20:32
add a comment |
Nice answer. Although I don't think the outside[, 1:2]
subset is necessary since you've already done that subset inside theabs()
call.
– Rich Scriven
Jan 23 at 20:25
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the[, 2:3]
subset.
– markus
Jan 23 at 20:32
Nice answer. Although I don't think the outside
[, 1:2]
subset is necessary since you've already done that subset inside the abs()
call.– Rich Scriven
Jan 23 at 20:25
Nice answer. Although I don't think the outside
[, 1:2]
subset is necessary since you've already done that subset inside the abs()
call.– Rich Scriven
Jan 23 at 20:25
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the
[, 2:3]
subset.– markus
Jan 23 at 20:32
@RichScriven Thanks for your comment. I guess I included it in case OP changes their mind and want's to find the closest values to, say, column 1, in which case we'd need the
[, 2:3]
subset.– markus
Jan 23 at 20:32
add a comment |
Here is another approach using matrixStats
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
x[matrixStats::rowMins(y) == y]
# [1] 24 30 20
Or in base
using vapply
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
vapply(1:nrow(data),
function(k) x[k,][which.min(y[k,])],
numeric(1))
# [1] 24 30 20
add a comment |
Here is another approach using matrixStats
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
x[matrixStats::rowMins(y) == y]
# [1] 24 30 20
Or in base
using vapply
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
vapply(1:nrow(data),
function(k) x[k,][which.min(y[k,])],
numeric(1))
# [1] 24 30 20
add a comment |
Here is another approach using matrixStats
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
x[matrixStats::rowMins(y) == y]
# [1] 24 30 20
Or in base
using vapply
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
vapply(1:nrow(data),
function(k) x[k,][which.min(y[k,])],
numeric(1))
# [1] 24 30 20
Here is another approach using matrixStats
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
x[matrixStats::rowMins(y) == y]
# [1] 24 30 20
Or in base
using vapply
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
vapply(1:nrow(data),
function(k) x[k,][which.min(y[k,])],
numeric(1))
# [1] 24 30 20
edited Jan 23 at 14:12
answered Jan 23 at 13:47
natenate
3,1411321
3,1411321
add a comment |
add a comment |
A tidyverse
solution:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
select(val)
val
<dbl>
1 24
2 30
3 20
First, it adds a row ID. Second, it transforms the data from wide to long. Third, it calculates the difference between "x3" and the other variables. Finally, it groups by the row ID and keeps the rows where the absolute difference is the smallest.
Or:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
pull(val)
[1] 24 30 20
Or using an approach originally proposed by @markus (it assumes that your columns are named "x"):
data %>%
mutate(temp = paste0("x", max.col(-abs(.[, -3] - .[, 3])))) %>%
rowwise() %>%
summarise(val = eval(as.symbol(temp)))
val
<dbl>
1 24.
2 30.
3 20.
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest and combines it with "x". Then, it evaluates the combination of x and column index as a variable and returns the appropriate value.
Also borrowing the idea from @markus (not assuming that your columns are named "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest. Second, it returns the column name based on the column index. Finally, it evaluates it as a variable and returns the appropriate value.
Or a variant where you can reference the "x3" variable by its name and not by column index (the basic idea still from @markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
1
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that thetidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)
– tmfmnk
Jan 23 at 14:30
1
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
1
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler singlemutate
:data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result ofmax.col
but otherwise that’s it.
– Konrad Rudolph
Jan 24 at 9:57
1
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be onfortunes
.
– RLave
Jan 24 at 10:56
|
show 3 more comments
A tidyverse
solution:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
select(val)
val
<dbl>
1 24
2 30
3 20
First, it adds a row ID. Second, it transforms the data from wide to long. Third, it calculates the difference between "x3" and the other variables. Finally, it groups by the row ID and keeps the rows where the absolute difference is the smallest.
Or:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
pull(val)
[1] 24 30 20
Or using an approach originally proposed by @markus (it assumes that your columns are named "x"):
data %>%
mutate(temp = paste0("x", max.col(-abs(.[, -3] - .[, 3])))) %>%
rowwise() %>%
summarise(val = eval(as.symbol(temp)))
val
<dbl>
1 24.
2 30.
3 20.
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest and combines it with "x". Then, it evaluates the combination of x and column index as a variable and returns the appropriate value.
Also borrowing the idea from @markus (not assuming that your columns are named "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest. Second, it returns the column name based on the column index. Finally, it evaluates it as a variable and returns the appropriate value.
Or a variant where you can reference the "x3" variable by its name and not by column index (the basic idea still from @markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
1
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that thetidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)
– tmfmnk
Jan 23 at 14:30
1
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
1
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler singlemutate
:data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result ofmax.col
but otherwise that’s it.
– Konrad Rudolph
Jan 24 at 9:57
1
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be onfortunes
.
– RLave
Jan 24 at 10:56
|
show 3 more comments
A tidyverse
solution:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
select(val)
val
<dbl>
1 24
2 30
3 20
First, it adds a row ID. Second, it transforms the data from wide to long. Third, it calculates the difference between "x3" and the other variables. Finally, it groups by the row ID and keeps the rows where the absolute difference is the smallest.
Or:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
pull(val)
[1] 24 30 20
Or using an approach originally proposed by @markus (it assumes that your columns are named "x"):
data %>%
mutate(temp = paste0("x", max.col(-abs(.[, -3] - .[, 3])))) %>%
rowwise() %>%
summarise(val = eval(as.symbol(temp)))
val
<dbl>
1 24.
2 30.
3 20.
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest and combines it with "x". Then, it evaluates the combination of x and column index as a variable and returns the appropriate value.
Also borrowing the idea from @markus (not assuming that your columns are named "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest. Second, it returns the column name based on the column index. Finally, it evaluates it as a variable and returns the appropriate value.
Or a variant where you can reference the "x3" variable by its name and not by column index (the basic idea still from @markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
A tidyverse
solution:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
select(val)
val
<dbl>
1 24
2 30
3 20
First, it adds a row ID. Second, it transforms the data from wide to long. Third, it calculates the difference between "x3" and the other variables. Finally, it groups by the row ID and keeps the rows where the absolute difference is the smallest.
Or:
data %>%
rowid_to_column() %>%
gather(var, val, -c(x3, rowid)) %>%
mutate(temp = x3 - val) %>%
group_by(rowid) %>%
filter(abs(temp) == min(abs(temp))) %>%
ungroup() %>%
pull(val)
[1] 24 30 20
Or using an approach originally proposed by @markus (it assumes that your columns are named "x"):
data %>%
mutate(temp = paste0("x", max.col(-abs(.[, -3] - .[, 3])))) %>%
rowwise() %>%
summarise(val = eval(as.symbol(temp)))
val
<dbl>
1 24.
2 30.
3 20.
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest and combines it with "x". Then, it evaluates the combination of x and column index as a variable and returns the appropriate value.
Also borrowing the idea from @markus (not assuming that your columns are named "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
First, it is assessing the column index of the variable where the absolute difference in regard to "x3" is the smallest. Second, it returns the column name based on the column index. Finally, it evaluates it as a variable and returns the appropriate value.
Or a variant where you can reference the "x3" variable by its name and not by column index (the basic idea still from @markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
edited Jan 24 at 6:23
answered Jan 23 at 14:00
tmfmnktmfmnk
3,0371514
3,0371514
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
1
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that thetidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)
– tmfmnk
Jan 23 at 14:30
1
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
1
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler singlemutate
:data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result ofmax.col
but otherwise that’s it.
– Konrad Rudolph
Jan 24 at 9:57
1
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be onfortunes
.
– RLave
Jan 24 at 10:56
|
show 3 more comments
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
1
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that thetidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)
– tmfmnk
Jan 23 at 14:30
1
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
1
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler singlemutate
:data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result ofmax.col
but otherwise that’s it.
– Konrad Rudolph
Jan 24 at 9:57
1
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be onfortunes
.
– RLave
Jan 24 at 10:56
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
I like that I can always count on you for a tidyverse approach but sometimes they look so complex and intimidating. Great all the same!
– NelsonGon
Jan 23 at 14:19
1
1
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that the
tidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)– tmfmnk
Jan 23 at 14:30
@NelsonGon sometimes it gets really verbose, that is true. But that is also true that the
tidyverse
aprroaches in general are not the ones with the shortest code. Anyway, thank you for your compliment :)– tmfmnk
Jan 23 at 14:30
1
1
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
This is a tidyverse solution, not the only one, and not one I'd write. You can make the code a lot less verbose by following the natural logic of the other answer, no need to reshape the data.
– Konrad Rudolph
Jan 23 at 17:19
1
1
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler single
mutate
: data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result of max.col
but otherwise that’s it.– Konrad Rudolph
Jan 24 at 9:57
@tmfmnk You’re completely right but just to clarify, I think in this case you’re torturing dplyr, and it confesses to anything. You could do a simpler single
mutate
: data %>% mutate(d = .[, -3][cbind(row_number(), max.col(- abs(.[, 3] - .[, -3])))])
— I’d be tempted to introduce a temporary column to hold the result of max.col
but otherwise that’s it.– Konrad Rudolph
Jan 24 at 9:57
1
1
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be on
fortunes
.– RLave
Jan 24 at 10:56
"I think in this case you’re torturing dplyr, and it confesses to anything", this could be on
fortunes
.– RLave
Jan 24 at 10:56
|
show 3 more comments
Define a function closest_to_3
that operates on a vector and returns the value in the vector that's closest to the third member:
closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]
(The idiom v[-3]
deletes the 3rd member from v
.) Then apply this function to each row of your data frame:
apply(data, 1, closest_to_3)
#[1] 24 30 20
add a comment |
Define a function closest_to_3
that operates on a vector and returns the value in the vector that's closest to the third member:
closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]
(The idiom v[-3]
deletes the 3rd member from v
.) Then apply this function to each row of your data frame:
apply(data, 1, closest_to_3)
#[1] 24 30 20
add a comment |
Define a function closest_to_3
that operates on a vector and returns the value in the vector that's closest to the third member:
closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]
(The idiom v[-3]
deletes the 3rd member from v
.) Then apply this function to each row of your data frame:
apply(data, 1, closest_to_3)
#[1] 24 30 20
Define a function closest_to_3
that operates on a vector and returns the value in the vector that's closest to the third member:
closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]
(The idiom v[-3]
deletes the 3rd member from v
.) Then apply this function to each row of your data frame:
apply(data, 1, closest_to_3)
#[1] 24 30 20
answered Jan 23 at 20:06
grand_chatgrand_chat
24111
24111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54328301%2fclosest-value-to-a-specific-column-in-r%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown