Far*_*rel 16 r missing-data zoo data.table
我正在为我的临床实践工作11年的大量计费记录数据.相当一部分行缺少转诊医生.但是,使用一些规则我可以很容易地填充它们但不知道如何在R中的data.table中实现它.我知道na.locf在zoo.table包中有诸如zoo包和自滚动连接之类的东西.我看到的例子过于简单,并没有帮助我.
这里有一些虚构的数据来定位你(作为一个输入ASCII文本表示)
structure(list(patient.first.name = structure(c(1L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), .Label = c("John", "Kathy",
"Timothy"), class = "factor"), patient.last.name = structure(c(3L,
3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("Jones",
"Martinez", "Squeal"), class = "factor"), medical.record.nr = c(4563455,
4563455, 4563455, 4563455, 4563455, 2663775, 2663775, 2663775,
2663775, 2663775, 3330956, 3330956, 3330956, 3330956), date.of.service = c(39087,
39112, 39112, 39130, 39228, 39234, 39244, 39244, 39262, 39360,
39184, 39194, 39198, 39216), procedure.code = c(44750, 38995,
40125, 44720, 44729, 44750, 38995, 40125, 44720, 44729, 44750,
44729, 44729, 44729), diagnosis.code.1 = c(456.87, 456.87, 456.87,
456.87, 456.87, 521.37, 521.37, 521.37, 521.37, 356.36, 456.87,
456.87, 456.87, 456.87), diagnosis.code.2 = c(413, 413, 413,
413, 413, 532.23, NA, NA, NA, NA, NA, NA, NA, NA), referring.doctor.first = structure(c(1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, NA, NA, NA, 1L, 1L, NA), .Label = c("Abe",
"Mark"), class = "factor"), referring.doctor.last = structure(c(1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, NA, NA, NA, 1L, 1L, NA), .Label = c("Newstead",
"Wydell"), class = "factor"), referring.docotor.zip = c(15209,
15209, 15209, 15209, 15209, 15222, 15222, 15222, NA, NA, NA,
15209, 15209, NA), some.other.stuff = structure(c(1L, 1L, 1L,
NA, 3L, NA, NA, 4L, NA, 6L, NA, 2L, 5L, NA), .Label = c("alkjkdkdio",
"cheerios", "ddddd", "dddddd", "dogs", "lkjljkkkkk"), class = "factor")), .Names = c("patient.first.name",
"patient.last.name", "medical.record.nr", "date.of.service",
"procedure.code", "diagnosis.code.1", "diagnosis.code.2", "referring.doctor.first",
"referring.doctor.last", "referring.docotor.zip", "some.other.stuff"
), row.names = c(NA, 14L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)
显而易见的解决方案是在refer.doctor.last和refer.doctor.first上使用某种最后一次观察结果(LOCF)算法.但是,当它到达新患者时必须停止.换句话说,LOCF必须仅应用于由patient.first.name,patient.last.name,medical.record.nr的组合识别的一名患者.还要注意一些患者在第一次就诊时是否错过了转诊医生,这意味着必须向后推进一些观察.更复杂的是,一些患者会改变初级保健医生,因此可能会有一位早期转诊医生和另一位稍后转诊医生.因此,算法需要知道具有缺失值的行的日期顺序.
在动物园里,na.locf我没有看到每个病人分组LOCF的简单方法.我看到的滚动连接示例在这里不起作用因为我不能简单地删除缺少refer.doctor信息的行,因为我将松开date.of.service和procedure.code等.我很乐意帮助您了解R如何填写我的遗失数据.
Mat*_*wle 21
一个更简洁的例子会更容易回答.例如,您已经包含了很多看似冗余的列.它真的需要名字和姓氏,还是我们可以使用患者号码?
既然你已经有了NAS IN的数据,您要填写,它不是roll在data.table真的.一个滚动的加入更是当你的数据没有进行NA,但你有另一种连接到位置的时间序列(例如)插图中的数据.(一个效率优势是你首先不创建NA,然后你必须填写第二步.)或者换句话说,在你的问题中你只有一个数据集; 你没有加入两个.
所以你确实需要na.locf@Joshua建议.但是我不知道一个NA向前填充的函数,然后是向后的第一个值.
在data.table,na.locf通过组使用它只是:
require(data.table)
require(zoo)
DT[,doctor:=na.locf(doctor),by=patient]
Run Code Online (Sandbox Code Playgroud)
具有快速聚合和参考更新的效率优势.你必须在顶部写一个新的小函数na.locf来NA向后滚动第一个非函数.
确保首先按患者和日期对数据进行排序.然后,上述将应对医生随时间的变化,因为by维持每组内行的顺序.
希望能给你一些提示.
Far*_*rel 21
@MatthewDowle为我们提供了一个很好的起点,在这里我们将结束它.
简而言之,用动物园的na.locf.问题不适合滚动连接.
setDT(bill)
bill[,referring.doctor.last:=na.locf(referring.doctor.last,na.rm=FALSE),
by=list(patient.last.name, patient.first.name, medical.record.nr)]
bill[,referring.doctor.last:=na.locf(referring.doctor.last,na.rm=FALSE,fromLast=TRUE),
by=list(patient.last.name, patient.first.name, medical.record.nr)]
Run Code Online (Sandbox Code Playgroud)
然后做类似的事情 referring.doctor.first
几点建议:
该by声明确保结转的最后一次观察仅限于同一患者,以便携带不会"流血"到列表中的下一位患者身上.
必须使用这个na.rm=FALSE论点.如果没有,那么在第一次就诊时缺少推荐医生信息的患者将被NA移除,并且新值(现有+结转)的向量将是行数不足的一个元素.缩短的向量被循环使用,一切都向上移动,最后一行得到向量的第一个元素,因为它被循环使用.换句话说,一团糟.最糟糕的是,你有时只会看到它.
用于fromLast=TRUE再次运行该列.这填补了任何数据之前的NA.而不是最后一次观察结果(LOCF)动物园使用下一个观察结果(NOCB).幸福 - 您现在已经以大多数情况下正确的方式填写了缺失的数据.
你可以:=每行传递多个,例如DT[,`:=`(new=1L,new2=2L,...)]