有条件地计算另一列中的值的一列的递归

时间:2018-02-19 20:29:56

标签: c recursion multidimensional-array

我获得了名为Temp.dat的数据集,其中包含2列(Dataset here)。我最初形成了名为structure data_t data[100]的结构,以便我可以根据第一列按递增顺序排列列(第0列=最小(失败时间,审查时间),第1列表示1 =死亡观察,0 =审查观察。结构化数据集的一部分具有以下形式

0.064295 1 
0.070548 1 
0.070850 1 
0.071508 0 
0.077981 1 
0.086628 1 
0.088239 1 
0.090754 1 
0.093260 0 
0.094090 1 
0.094367 1 
0.097019 1 
0.099336 1 
0.103765 1 
0.103961 1 
0.111674 0 
0.122609 0 
0.123730 1 

现在,我想编写C代码以形成不同的时间段,其端点始终以第2列中的条目1结束。看起来如下:

预期输出 - 添加第3列(时间间隔)

0.064295 1 [0 0.064295)        
0.070548 1 [0.064295 0.070548) 
0.070850 1 [0.070548 0.070850) 
0.071508 0 [0.070850 0.077891) ---> Skip 0.071508 here because of 0 in column 1 
0.077981 1 [0.070850 0.077981)
0.086628 1 [0.077981 0.086628) 
0.088239 1 [0.086628 0.088239) 
0.090754 1 [0.088239 0.090754) 
0.093260 0 [0.090754 0.094090) 
0.094090 1 [0.090754 0.094090) 
0.094367 1 [0.094090 0.094367) 
0.097019 1 [0.094367 0.097019) 
0.099336 1 [0.097019 0.099336) 
0.103765 1 [0.099336 0.103765) 
0.103961 1 [0.103765 0.103961) 
0.111674 0 [0.103961 0.123730) 
0.122609 0 [0.103961 0.123730) 
0.123730 1 [0.103961 0.123730)

到目前为止,我无法编写代码来执行此操作。所以,如果有人能帮助我迈出这一步,我会真诚地感激它。

接下来,我编写了以下代码以获得如下所示的输出。请注意,第2列不是我想要的,但到目前为止,这是最佳的事情。

  double array[8][MAX];
  double total = 100;
  for(int i = 0; i < MAX; i++) { 
    double start = 0;
    double count = 0;
    if(i) start = data[i - 1].x; 
    array[0][i] = data[i].x; 
    array[1][i] = data[i].y; 
    array[2][i] = start; 
    array[3][i] = data[i].x;
    array[4][0] = count;
    array[5][0] = count;
    array[6][0] = total;
    array[7][0] = 1;
    /*keep track of number of deaths and censors at each time t_i*/
    if (fmod(arr[1][i], 2.0) == 1)
      {arr[4][i+1]  = count + 1.0;
       arr[5][i+1]  = count;
      }
    else {arr[4][i+1] = count;
          arr[5][i+1] = count + 1.0;
         }

  return(0);
}

示例输出

0.064295 1 [0.060493 0.064295) 1.000000 0.000000 191.000000 0.950000
0.070548 1 [0.064295 0.070548) 1.000000 0.000000 190.000000 0.945000
0.070850 1 [0.070548 0.070850) 1.000000 0.000000 189.000000 0.940000
0.071508 0 [0.070850 0.071508) 1.000000 0.000000 188.000000 0.940000
0.077981 1 [0.071508 0.077981) 0.000000 1.000000 187.000000 0.935000
0.086628 1 [0.077981 0.086628) 1.000000 0.000000 186.000000 0.929973
0.088239 1 [0.086628 0.088239) 1.000000 0.000000 185.000000 0.924946
0.090754 1 [0.088239 0.090754) 1.000000 0.000000 184.000000 0.919919
0.093260 0 [0.090754 0.093260) 1.000000 0.000000 183.000000 0.919919

第7列代表生存分布函数的KM估计。它是根据以下规则计算的:  1.如果第1列中的第i个条目为0,则只需将第6列中相应的第i个条目保存为等于同一列中的前一个(第i-1)个条目。  2.如果第1列中的第i个条目为1,但在它为0之前有一个或多个连续条目(例如,第1列的最后一个条目紧跟在前两个0之后),我们计算相应的 i第6列中的第条目,其公式为:(i-1)-th entry *(1- 1 /(第5列中的第j个条目))其中第5列中的第j个条目对应于第1列中最近条目1(例如,第1列的最后4行中包含1 0 0 1,这意味着第6列中的最后一个条目将计算为0.890096*(1-1/177)其中177 =第5列中的第一个条目,其中第1列= 1(而不是0)中有相应的条目。

任务完成:首先,我需要形成正确第2列,以便随机输入 t在范围内第0列,代码将在第6列中给出相应的结果。

其次,我想计算KM估计量的方差,使用以下公式:S(t)^ 2 *(t_i <= t的总和)d_i /(r_i *(r_i-d_i)),

其中S(t)=在时间t计算的KM估计量(上面的第7列),d_i是直到索引i的死亡总数(因此,直到上面第5列的d_i的条目总和),r_i =第6列中的第i个条目。例如,如果t = 0.071,则t_i仅具有基于列0的3个可能值(t_i将为0.064295,0.070548和0.070850)。我想出了以下工作代码(不确定输出是否正确)

  N = [an integer]; #define size of array here
  double sigma[N];
  sigma[0] = 0;
  double sum[N];
  sum[0] = 0;
  for(int i=1; i< N; i++){
     sum[i] = sum[i-1] + (float)(arr[4][i]/(arr[6][i-1]*(arr[6][i])));
     sigma[i] = pow(arr[7][i],2)*sum[i];
     printf("%.0lf", sigma[i]);
  }

示例输出

0.004775
0.004750
0.004725
0.004700
0.004675
0.004700
0.004650
0.004625
0.004600
0.004575
0.004600
0.004550
0.004525
0.004500
0.004475
0.004450
0.004425
0.004450
0.004450
0.004400
0.004375
0.004350
0.004325
0.004300
0.004275
0.004250
0.004225
0.004200
0.004175
0.004149
0.004124
0.004150
0.004099
0.004074
0.004100
0.004049
0.004024
0.004051
0.003999
0.003974
0.004001
0.003949
0.003976
0.003923
0.003898
0.003926
0.003873
0.003848
0.003823
0.003797
0.003772
0.003747
0.003775
0.003722
0.003750
0.003696
0.003725
0.003671
0.003700
0.003646
0.003676
0.003621
0.003595
0.003570
0.003544
0.003519
0.003549
0.003494

1 个答案:

答案 0 :(得分:1)

这是部分答案。首先,让我们将数组声明为arr[MAX][8],这意味着您有MAX行和8列。这样可以更轻松地对数据进行排序。

接下来,让我们创建更容易查看的虚拟数据0.100, 0.101, ...

要查找第5列,您可以使用其他循环(for(int j = i; j < count; j++){...})来查找下一个非零值。

我们必须跟踪总死亡人数(dead_count)并在每次arr[i][1]为零时递增。

Kaplan-Meier公式被视为1 - (double)dead_count/(double)count

MCVE看起来像:

#include <stdlib.h>
#include <stdio.h>

int compare_2d_array(const void *pa, const void *pb)
{
    double a = *(double*)pa;
    double b = *(double*)pb;
    if(a > b) return 1;
    if(a < b) return -1;
    return 0;
}

int main(void)
{
    double arr[][8] =
    {
        { 0.100, 1, 0, 0, 0, 0, 0 , 0 }, //initialize columns
        { 0.101, 1 }, // we can skip adding the zeros, it's done automatically
        { 0.102, 1 },
        { 0.103, 0 },
        { 0.104, 1 },
        { 0.105, 1 },
        { 0.106, 1 },
        { 0.107, 1 },
        { 0.108, 0 },
        { 0.109, 1 },
        { 0.110, 1 },
        { 0.111, 1 },
        { 0.112, 1 },
        { 0.113, 1 },
        { 0.114, 1 },
        { 0.115, 0 },
        { 0.116, 0 },
        { 0.117, 1 },
    };

    int count = sizeof(arr)/sizeof(*arr);

    //sort
    qsort(arr, count, sizeof(arr[0]), compare_2d_array);

    int dead_count = 0;
    for(int i = 0; i < count; i++)
    {
        double start = i ? arr[i - 1][0] : 0;
        double end = arr[i][0]; //<- I don't know what to use as default value!

        //if arr[i][1] is zero, then end should equal the next non-zero value
        double end;
        for(int j = i; j < count; j++)
        {
            end = arr[j][0];
            if(arr[j][1])
                break;
        }

        arr[i][2] = start;
        arr[i][3] = end;
        arr[i][4] = arr[i][1];
        arr[i][5] = !arr[i][1];

        if(!arr[i][1])
            dead_count++;

        printf("%3d %.6lf %.0lf [%.6lf %.6lf) %.0lf %.0lf %3d %.6lf\n", 
            i, 
            arr[i][0], 
            arr[i][1], 
            start,
            end, 
            arr[i][4], 
            arr[i][5], 
            count - i, 1 - (double)dead_count/(double)count );
    }

    return 0;
}

输出:

  0 0.100000 1 [0.000000 0.100000) 1 0  18 1.000000
  1 0.101000 1 [0.100000 0.101000) 1 0  17 1.000000
  2 0.102000 1 [0.101000 0.102000) 1 0  16 1.000000
  3 0.103000 0 [0.102000 0.104000) 0 1  15 0.944444
  4 0.104000 1 [0.103000 0.104000) 1 0  14 0.944444
  5 0.105000 1 [0.104000 0.105000) 1 0  13 0.944444
  6 0.106000 1 [0.105000 0.106000) 1 0  12 0.944444
  7 0.107000 1 [0.106000 0.107000) 1 0  11 0.944444
  8 0.108000 0 [0.107000 0.109000) 0 1  10 0.888889
  9 0.109000 1 [0.108000 0.109000) 1 0   9 0.888889
 10 0.110000 1 [0.109000 0.110000) 1 0   8 0.888889
 11 0.111000 1 [0.110000 0.111000) 1 0   7 0.888889
 12 0.112000 1 [0.111000 0.112000) 1 0   6 0.888889
 13 0.113000 1 [0.112000 0.113000) 1 0   5 0.888889
 14 0.114000 1 [0.113000 0.114000) 1 0   4 0.888889
 15 0.115000 0 [0.114000 0.117000) 0 1   3 0.833333
 16 0.116000 0 [0.115000 0.117000) 0 1   2 0.777778
 17 0.117000 1 [0.116000 0.117000) 1 0   1 0.777778