как ранжировать столбец чисел при сохранении исходной позиции каждого числа - PullRequest
1 голос
/ 23 октября 2019

Я хотел бы написать код для критерия Уилкоксона со знаком для медианы (статистический непараметрический тест), потому что мне нужно делать это сотни раз. Я застрял в коде для важного шага теста и надеялся, что кто-нибудь сможет помочь.

Тест включает следующие шаги:

  1. начать со столбца значений

  2. вычесть постоянную из каждого значения, чтобы получить столбец различий (с сохранением знака +/-)

  3. Теперь удалите все - знаки, чтобы получить только положительные значения (таким образом, абсолютные различия)

  4. ранжируйте эти абсолютные различия по порядку величины (от 1 до n)

  5. добавить ранги, связанные только с положительными различиями на шаге 2.

Я застрял на шаге 5: как связать ранги со значениями на шаге 2?
Здесьэто то, что у меня есть:

//Subtract HypMed from values in Column and put abs diffs in array
SetLength(AbsDiffVals, CtrlsList.Count)
for J := 0 to CtrlsList.Count - 1 do 
begin
  Diff := StrToFloat(CtrlsList[J]) - StrToFloat(HypMed);
  DiffVals.Add(FloatToStr(Diff));
  AbsDiff := Abs(Diff);
  AbsDiffVals[J] := AbsDiff;
end;

И

//sort array AbsDiffVals
for J := 0 to Length(AbsDiffVals)-2 do
begin
  for K := J+1 to Length(AbsDiffVals)-1 do
  begin
    if AbsDiffVals[J] < AbsDiffVals[K] then continue
    else if AbsDiffVals[J] > AbsDiffVals[K] then
    begin
      Temp1 := AbsDiffVals[J];
      Temp2 := AbsDiffVals[K];
      AbsDiffVals[J] := Temp2;
      AbsDiffVals[K] := Temp1;
    end;
  end;
end;

Теперь мне нужно связать позицию каждого значения в массиве (AbsDiffVals), который является рангом значения, с соответствующим знаком в DiffVals TStringList. Вот где я застрял и хотел бы помочь.

1 Ответ

0 голосов
/ 24 октября 2019

Мне кажется, я понял код для ответа на мой вопрос, но у меня есть пара вопросов. Вот кодЯ задам вопросы после кода.

//Subtract HypMed from values in Column and put abs diffs in array
SetLength(AbsDiffVals, CtrlsList.Count)
for J := 0 to CtrlsList.Count - 1 do 
begin
  Diff := StrToFloat(CtrlsList[J]) - StrToFloat(HypMed);
  DiffVals.Add(FloatToStr(Diff));
  AbsDiff := Abs(Diff);
  AbsDiffVals[J] := AbsDiff;
end;

И

//sort array AbsDiffVals
for J := 0 to Length(AbsDiffVals)-2 do
begin
  for K := J+1 to Length(AbsDiffVals)-1 do
  begin
    if AbsDiffVals[J] < AbsDiffVals[K] then continue
    else if AbsDiffVals[J] > AbsDiffVals[K] then
    begin
      Temp1 := AbsDiffVals[J];
      Temp2 := AbsDiffVals[K];
      AbsDiffVals[J] := Temp2;
      AbsDiffVals[K] := Temp1;
    end;
  end;
end;   

//put the absolute diffs in a TStringList
for J := 0 to Length(AbsDiffVals)-1 do
begin
  AbsDiffValsList.Add(FloatToStr(AbsDiffVals[J]));
end;

//associate the sorted values with the sign of corresponding value in DiffVals
//also assign - sign to rank if sign in DiffVals is -; else + sign
SetLength(RankVals, Length(AbsDiffVals));
for J := 0 to DiffVals.Count - 1 do
begin
  Temp := Abs(StrToFloat(DiffVals[J]));
  Rank := AbsDiffValsList.IndexOf(FloatToStr(Temp))+1;//Find the rank of the value
  if StrToFloat(DiffVals[J]) < 0 then Rank := Rank * -1
  else Rank := Rank * 1;
  RankVals[J] := Rank;
end;

//replace all negative ranks with 0 and retain all positive ranks
for J := 0 to Length(RankVals) - 1 do
begin
  if RankVals[J] < 0 then RankVals[J] := 0
  else continue;
end;               

//store modified ranks (0 if negative) in TSTringList for easy saving to file
for J := 0 to Length(RankVals) - 1 do
begin
  RankList.Add(IntToStr(RankVals[J]));
end;

Этот код, кажется, делает то, что мне нужно, - для моих образцов данных, которые ведут себя хорошо,Тем не менее, я хочу сделать это надежным, потому что у меня есть сотни наборов данных, некоторые из которых, возможно, не так хорошо себя ведут. Два способа, которыми данные могут быть хитрыми (и мой код явно не имеет с ними дело):

  1. Что если два значения идентичны? Мой код явно не касается связей. Связанным значениям следует присвоить средний ранг.
  2. Что если два (или более) значения равноудалены от константы, но одно больше, а другое меньше? Затем, после удаления знака в AbsDiffs, я не смогу их различить.

Есть предложения?

...