R 中特定列的最接近值
Closest value to a specific column in R
我想找到最接近下面第 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
请帮忙。谢谢
使用 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
这是另一种使用 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
一个tidyverse
解决方案:
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
首先,它添加了一个行 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() %>%
pull(val)
[1] 24 30 20
或使用最初由@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"绝对差值最小的变量的列索引,并与"x"合并。然后,它评估 x 和列索引的组合作为变量和 returns 适当的值。
还借鉴了@markus 的想法(不假设您的列被命名为 "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
首先,评估与"x3"绝对差值最小的变量的列索引。其次,它 returns 基于列索引的列名。最后,它将其评估为一个变量,returns 适当的值。
或者一个变体,您可以通过名称而不是列索引引用 "x3" 变量(基本思想仍然来自@markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
定义一个函数 closest_to_3
对向量进行运算,returns 向量中最接近第三个成员的值:
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
我想找到最接近下面第 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
请帮忙。谢谢
使用 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
这是另一种使用 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
一个tidyverse
解决方案:
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
首先,它添加了一个行 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() %>%
pull(val)
[1] 24 30 20
或使用最初由@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"绝对差值最小的变量的列索引,并与"x"合并。然后,它评估 x 和列索引的组合作为变量和 returns 适当的值。
还借鉴了@markus 的想法(不假设您的列被命名为 "x"):
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
首先,评估与"x3"绝对差值最小的变量的列索引。其次,它 returns 基于列索引的列名。最后,它将其评估为一个变量,returns 适当的值。
或者一个变体,您可以通过名称而不是列索引引用 "x3" 变量(基本思想仍然来自@markus):
data %>%
mutate(temp = max.col(-abs(.[, !grepl("x3", colnames(.))] - .[, grepl("x3", colnames(.))]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
定义一个函数 closest_to_3
对向量进行运算,returns 向量中最接近第三个成员的值:
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