如何用另一列的条件分组并填充R数据帧列中最接近的NA

时间:2019-07-02 16:05:02

标签: r na

我有一个血液测试标记结果的数据框,我想按以下标准填写NA:

对于每个ID组(时间按升序排列),如果标记值是NA,则用该组中最接近的非NA值(可能是过去或将来)填充它,但前提是时差小于14

我的数据示例:

df<-data.frame(ID=c(rep(2,5),rep(4,3)), TIME =c(1,22,33,43,85,-48,1,30),
           CEA = c(1.32,1.42,1.81,2.33,2.23,29.7,23.34,18.23),
           CA.15.3 = c(14.62,14.59,16.8,22.34,36.33,56.02,94.09,121.5),
           CA.125 = c(33.98,27.56,30.31,NA,39.57,1171.00,956.50,825.30),
           CA.19.9 = c(6.18,7.11,5.72, NA, 7.38,39.30,118.20,98.26),
           CA.72.4 = c(rep(NA,5),1.32, NA, NA),
           NSE = c(NA, 13.21, rep(NA,6)))

ID TIME   CEA CA.15.3  CA.125 CA.19.9 CA.72.4   NSE
2    1  1.32   14.62   33.98    6.18      NA    NA
2   22  1.42   14.59   27.56    7.11      NA 13.21
2   33  1.81   16.80   30.31    5.72      NA    NA
2   43  2.33   22.34      NA      NA      NA    NA
2   85  2.23   36.33   39.57    7.38      NA    NA
4  -48 29.70   56.02 1171.00   39.30    1.32    NA
4    1 23.34   94.09  956.50  118.20      NA    NA
4   30 18.23  121.50  825.30   98.26      NA    NA    

ID是患者。 TIME是血液检查的时间。 其他是标记。

我能做到的唯一方法是尽量避免循环。

我希望输出为:

ID TIME   CEA CA.15.3  CA.125 CA.19.9 CA.72.4   NSE
2    1  1.32   14.62   33.98    6.18      NA    NA
2   22  1.42   14.59   27.56    7.11      NA 13.21
2   33  1.81   16.80   30.31    5.72      NA 13.21
2   43  2.33   22.34   30.31    5.72      NA    NA
2   85  2.23   36.33   39.57    7.38      NA    NA
4  -48 29.70   56.02 1171.00   39.30    1.32    NA
4    1 23.34   94.09  956.50  118.20      NA    NA
4   30 18.23  121.50  825.30   98.26      NA    NA  

CA.19.9和CA.124充满了前一个(之前10天) NSE充满了过去的11天

CA.72.4未填充,因为时差为1.32(即-48)距离下一个度量标准还有49天。

2 个答案:

答案 0 :(得分:1)

我敢打赌,这里有一个更简单的矢量化解决方案,但以下工作可行。

#!/usr/bin/env sh

read_path() {
    path=
    IFS=
    read -r path || return $?
    read -r path_next || return 0
    if [ X"$path" = X"././" ]; then
        path="./"
        read -r path_next || return 0
        return
    fi
    path="./$path"
    while [ X"$path_next" != X"././" ]; do
        path=`printf '%s\n%s' "$path" "$path_next"`
        read -r path_next || return 0
    done
}

find ././ |sed 's,^\./\./,&\n,' |while read_path; do
  echo "$path"
done

答案 1 :(得分:1)

是的,您可以使用向量化解决方案。首先让我们考虑您仅使用未来价值进行估算的情况。您需要创建一些辅助变量:

  1. 一个变量,它告诉您下一个观察值是否属于相同的ID(因此可以用于估算),
  2. 一个变量,告诉您下一次观察是否与当前观察相距不到14天。

这些不依赖于要插入的特定变量。对于要估算的每个变量,您还需要一个变量,该变量告诉您​​是否缺少下一个变量。

然后,您可以向量化以下逻辑:当下一个观测值具有相同的id,并且距当前观测值少于14天且没有丢失时,将其值复制到当前观测值中。

当您需要决定使用过去或将来的值时,事情变得更加复杂,但是逻辑是相同的。代码在下面,有点长,但是您可以简化一下,我只是想弄清楚它的作用。

希望这会有所帮助

Rand g