回答:
このスクリプトは同じことを行います(さらにもう少し)。
function myInterpolation(x, y, value) {
if(value > Math.max.apply(Math, x) || value < Math.min.apply(Math, x)) {
throw "value can't be interpolated !!";
return;
}
var check = 0, index;
for(var i = 0, iLen = x.length; i < iLen; i++) {
if(x[i][0] == value) {
return y[i][0];
} else {
if(x[i][0] < value && ((x[i][0] - check) < (value - check))) {
check = x[i][0];
index = i;
}
}
}
var xValue, yValue, xDiff, yDiff, xInt;
yValue = y[index][0];
xDiff = x[index+1][0] - check;
yDiff = y[index+1][0] - yValue;
xInt = value - check;
return (xInt * (yDiff / xDiff)) + yValue;
}
スクリプトの最初に、小さなエラー処理があります。その後、入力値と比較して最初に最も低いエントリを見つけます。見つかったら、いくつかの計算を行い、結果を表示します。
選択した値が20の場合、スクリプトは、数式が生成する150を返します#DIV/0
。
次の式を使用して、すべての値を考慮に入れます
=IF(
ISNA(
MATCH(C2,A2:A7,0)),
FORECAST(
$C$2,
OFFSET(B$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1),
OFFSET(A$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1)),
INDEX(
B2:B7,
MATCH(C2,A2:A7,0)
,0)
)
copy / paste
=IF(ISNA(MATCH(C2, A2:A7, 0)), FORECAST($C$2,OFFSET(B$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1),OFFSET(A$2,MATCH($C$2,A$2:A$7,1)-1,0,2,1)), INDEX(B2:B7, MATCH(C2, A2:A7, 0), 0))
[ツール]> [スクリプトエディター]でスクリプトを追加し、[保存]ボタンを押します(認証は必要ありません)。
サンプルファイルを作成しました:Googleスプレッドシートで範囲内のデータを補間する方法
私はそれを行う方法を見つけました-より良い方法があるかもしれませんが、これは私が思いついたものです:
データがA1:B10にあり、$ C $ 1に検索するキーが含まれていると仮定します。
=FORECAST($C$1,
OFFSET(B$1,MATCH($C$1,A$1:A$10,1)-1,0,2,1),
OFFSET(A$1,MATCH($C$1,A$1:A$10,1)-1,0,2,1))
詳細に:
FORECASTは線形補間を行いますが、直線を想定しています。したがって、探している値を囲む2つの値を見つける必要があります。
したがって、MATCHを使用して、探しているもの以上の最初の数値を見つけます。
FORECASTはデータ範囲を想定しているため、OFFSETを使用してデータ範囲への参照を作成します。MATCHは1インデックスなので、最初に1を引く必要があります。1つの幅と2つの高さの範囲を作成します。この値には、検索値$ C $ 1が含まれることが保証されています。
x=20
すると、になり#DIV/0
ます。
これはJacob Jan Tuinstraのスクリプトを少し変更したものであり、配列または値を3番目の引数として取ることができるため、補間された関数を一度に多くの場所で計算できます。唯一の違いは、最初に追加された数行です。これは、ほとんどすべてのカスタム関数を、配列を受け入れるカスタム関数にすばやく変換する方法です。
function myInterpolation(x, y, value) {
if (value.map) {
return value.map(function(v) {
return myInterpolation(x, y, v);
});
}
// the rest stays the same
if (value > Math.max.apply(Math, x) || value < Math.min.apply(Math, x)) {
throw "value can't be interpolated !!";
return;
}
var check = 0, index;
for(var i = 0, iLen = x.length; i < iLen; i++) {
if(x[i][0] == value) {
return y[i][0];
} else {
if(x[i][0] < value && ((x[i][0] - check) < (value - check))) {
check = x[i][0];
index = i;
}
}
}
var xValue, yValue, xDiff, yDiff, xInt;
yValue = y[index][0];
xDiff = x[index+1][0] - check;
yDiff = y[index+1][0] - yValue;
xInt = value - check;
return (xInt * (yDiff / xDiff)) + yValue;
}