我尝试在na.trim
对象的单个列上使用包zoo
中的data.table
。这是我的数据:
DT <- data.table(id=c(rep("a",3),rep("b",3)),
col1=c(NA,1,2,NA,3,NA),col2=c(NA,NA,5,NA,NA,NA))
id col1 col2
1: a NA NA
2: a 1 NA
3: a 2 5
4: b NA NA
5: b 3 NA
6: b NA NA
我想使用na.trim
和ID分组删除前导 NAs的行。这是我期待的结果:
id col1 col2
1: a 1 NA
2: a 2 5
3: b 3 NA
4: b NA NA
这是我到目前为止所尝试的内容。这将删除前导NA但删除col2:
DT[,na.trim(col1),by=id]
id V1
1: a 1
2: a 2
3: b 3
这也行不通:
DT[,.SD[na.trim(col1)],by=id]
id col1 col2
1: a NA NA
2: a 1 NA
3: b NA NA
答案 0 :(得分:4)
不使用zoo
包的可能解决方案:
DT[DT[, .I[!!cumsum(!is.na(col1))], by = id]$V1]
你得到:
id col1 col2
1: a 1 NA
2: a 2 5
3: b 3 NA
4: b NA NA
这是做什么的:
DT[, .I[!!cumsum(!is.na(col1))], id]$V1
创建一个要保留的rownumbers矢量。通过使用!!cumsum(!is.na(col1))
,您可以确保只省略col1
的缺失值。!!cumsum(!is.na(col1))
与cumsum(!is.na(col1))!=0
的功能相同。使用!!
将所有大于零的数字转换为TRUE
,将所有零转换为FALSE
。.I
不是必需的,您也可以使用:DT[DT[, !!cumsum(!is.na(col1)), by = id]$V1]
使用逻辑向量对data.table进行子集化。来自评论的@lmo的cummax
的两个备选方案:
# alternative 1:
DT[DT[, !!(cummax(!is.na(col1))), by = id]$V1]
# alternative 2:
DT[as.logical(DT[, cummax(!is.na(col1)), by = id]$V1)]
@jogo的另一种选择:
DT[, .SD[!!cumsum(!is.na(col1))], by = id]
@Frank的另一种选择:
DT[, .SD[ rleid(col1) > 1L | !is.na(col1) ], by = id]
答案 1 :(得分:4)
na.trim
将与data.table一样使用。有关其参数的更多信息,请参阅?na.trim
。
DT[, na.trim(.SD, sides = "left", is.na = "all"), by = id]
,并提供:
id col1 col2
1: a 1 NA
2: a 2 5
3: b 3 NA
4: b NA NA
增加:
在评论中,海报澄清说,na.trim
只应对第1列NAs进行操作。在这种情况下,添加一列行号,.I,并在使用这些行号后使用na.trim
子集。
DT[DT[, na.trim(data.table(col1, .I), "left"), by = id]$.I, ]