问题描述
示例数据:
library(data.table)
set.seed(1)
DT <- data.table(panelID = sample(10,10),some_NA = sample(0:5,6),some_NA_factor = sample(0:5,Group = c(rep(1,20),rep(2,rep(3,rep(4,rep(5,20)),Time = rep(seq(as.Date("2010-01-03"),length=20,by="1 month") - 1,5),wt = 15*round(runif(100)/10,2),Income = round(rnorm(10,-5,Happiness = sample(10,Sex = round(rnorm(10,0.75,0.3),Age = sample(100,100),Height= 150*round(rnorm(10,2))
# ERRORS
DT [1:5,11] <- 0
在Height
数据注册中出现一些错误。由于数据是面板数据,因此我应该能够从其他观察结果推论出实际的Height
。为了使这一过程自动化,我想到了如果该值距离中值超过50厘米,则用中值替换一个值:
setDT(DT)[abs(median(Height,na.rm = TRUE) - Height) > 50,newheight := median(Height,na.rm = TRUE),by=panelID]
然而,by
自变量不起作用,导致以下结果:
> table(DT$newheight)
0 27 165
4 10 10
有人可以告诉我我在做什么错吗?
解决方法
您的问题按操作顺序排列。首先,将过滤器(即逗号前的位)应用于整个表格,因此此处计算的中位数是整个“高度”列的中位数。然后,在每个组中将逗号后的位应用于过滤后的数据。因此,您实际上使用的是异常值的中位数 ,而不是整个组的中位数(我认为这是您的预期)。
一种解决方法是分阶段进行:
prompt# robot --prerunmodifier modifier.MyModifier --pythonpath ./ test.robot
suite keywords - [Custom Suite Setup Keyword]
class - <class 'robot.running.model.Keyword'>
name - Custom Suite Setup Keyword
id - s1-k1
parent(suite) - Test
timeout - None
type - setup
doc -
tags - []
children - []
==============================================================================
Test
==============================================================================
A test | PASS |
------------------------------------------------------------------------------
Test | PASS |
1 critical test,1 passed,0 failed
1 test total,0 failed
==============================================================================
或者,您可能打算用以下内容代替最后一行:
setDT(DT)
DT[,median.height:= median(Height,na.rm = TRUE),by='panelID']
DT[abs(Height - median.height) > 50,newheight:= median.height]
,
尝试:
setDT(DT)
DT[,newheight := ifelse(abs(median(Height,na.rm = TRUE) - Height) > 50,median(Height,Height),by=.(panelID)]