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

标签 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)th- 条目。 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*(summation over 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 只有 3 个基于第 0 列的可能值(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

最佳答案

这是部分答案。首先,让我们将数组声明为 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

关于根据另一列中的值有条件地计算一列的递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48873704/

相关文章:

控制到达非空函数 c 的末尾

java - 旅行推销员 - 如何找到不等价的排列

c - C中的递归函数返回值而不返回

php - 代码分离悖论 : Create HTML Tree from Multi-Dimensional Array AND Keep the HTML Outside of the Recursive Function

计算数组的平方值的平均值

返回姓名首字母的 C 程序 (CS50)

c - 在 Linux 中创建静态库时出现问题

javascript - 递归:最少的步骤

Python Image.fromarray() 不接受从列表构建的 ndarray 输入

c++取消引用通过引用传递分配的指针,给出随机值