以下の列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
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を追加します。次に、データをワイドからロングに変換します。 3番目に、「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と列インデックスの組み合わせを変数として評価し、適切な値を返します。
また、@ markusからアイデアを借用しています(列の名前が「x」であるとは想定していません)。
data %>%
mutate(temp = max.col(-abs(.[, -3] - .[, 3]))) %>%
rowwise %>%
mutate(temp = names(.)[[temp]]) %>%
summarise(val = eval(as.symbol(temp)))
まず、 "x3"に関する絶対差が最も小さい変数の列インデックスを評価します。次に、列インデックスに基づいて列名を返します。最後に、それを変数として評価し、適切な値を返します。
または、列インデックスではなく名前で「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)))
これは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
関数を定義するclosest_to_3
はベクターを操作し、3番目のメンバーに最も近いベクターの値を返します。
closest_to_3 <- function(v) v[-3][which.min(abs( v[-3]-v[3] ))]
(イディオムv[-3]
は、3番目のメンバーをv
から削除します。)次に、この関数をデータフレームの各行に適用します。
apply(data, 1, closest_to_3)
#[1] 24 30 20