最接近R中特定列的值

时间:2019-01-23 13:24:03

标签: r dataframe closest

我想找到最接近下面x3列的值。

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

因此期望的输出将是

Closest_Value_to_x3
   24
   30
   20

请帮助。谢谢

4 个答案:

答案 0 :(得分:13)

使用max.col(-abs(data[, 3] - data[, -3]))查找最接近值的列位置,并将此结果用作矩阵的一部分从数据中提取所需的值。矩阵由cbind

返回
col <- 3
data[, -col][cbind(1:nrow(data),
                   max.col(-abs(data[, col] - data[, -col])))]
#[1] 24 30 20

答案 1 :(得分:3)

这是使用matrixStats

的另一种方法
x <- as.matrix(data[,-3L])
y <- abs(x - .subset2(data, 3L))
x[matrixStats::rowMins(y) == y]
# [1] 24 30 20

或者在base中使用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

答案 2 :(得分:3)

一种ember-source解决方案:

tidyverse

首先,它添加一个行ID。其次,它将数据从宽转换为长。第三,它计算“ x3”与其他变量之间的差。最后,它按行ID分组,并保留绝对差最小的行。

或者:

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

或使用@markus最初提出的方法(假定您的列名为“ x”):

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

首先,它评估变量的列索引,其中“ x3”的绝对差最小,并将其与“ x”组合。然后,它将x和列索引的组合评估为变量并返回适当的值。

还借鉴@markus的想法(不假设您的列名为“ 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.

首先,它评估变量的列索引,其中“ x3”的绝对差最小。其次,它基于列索引返回列名称。最后,它将其评估为变量并返回适当的值。

或者是一个变体,您可以通过其名称而不是按列索引来引用“ x3”变量(基本思想仍来自@markus):

data %>%
 mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
 rowwise %>%
 mutate(temp = names(.)[[temp]]) %>%
 summarise(val = eval(as.symbol(temp)))

答案 3 :(得分:2)

定义在向量上运行的函数closest_to_3,并返回向量中最接近第三个成员的值:

closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]

(习惯用法v[-3]v中删除第三个成员。)然后将此函数应用于数据框的每一行:

apply(data, 1, closest_to_3)
#[1] 24 30 20
相关问题