我正在尝试找出如何将ifelse语句与data.table中的shift函数结合在一起。我的数据如下:
DF <- structure(list(CHR = c(1, 1, 1, 1, 1,1),
SNP = c("rs2494631", "rs4648637", "rs2494627", "rs11122119", "rs1844583","rs2292242"),
BP = c(2399149, 2401364, 2402499, 6768856, 8383469, 8385059),
KBdist= c(NA, 2215, 1135, 4366357, 1614613, 1590),
locus = c(1, NA, NA, NA, NA, NA)),
.Names = c("CHR","SNP","BP","KBdist","locus"),
row.names = c(NA, 6L),
class = "data.frame")
> df
CHR SNP BP KBdist locus
1 rs2494631 2399149 NA 1
1 rs4648637 2401364 2215 NA
1 rs2494627 2402499 1135 NA
1 rs11122119 6768856 4366357 NA
1 rs1844583 8383469 1614613 NA
1 rs2292242 8385059 1590 NA
和我想实现的是: “如果CHR等于线之上,并KBdist是不到50万,化妆轨迹等于线之上,否则增加一个以上线的价值。”这将产生一个输出,看起来像这样:
CHR SNP BP KBdist locus
1 rs2494631 2399149 NA 1
1 rs4648637 2401364 2215 1
1 rs2494627 2402499 1135 1
1 rs11122119 6768856 4366357 2
1 rs1844583 8383469 1614613 3
1 rs2292242 8385059 1590 3
我知道我可以使用移位来访问值以上的行中,例如:
DF<-DF[ , KBdist := BP - shift(BP, 1L, type="lag")]
由于这就是我创建的列中的一个。但我看不出如何将其扩展到包括上述ifelse语句条件。
任何帮助将不胜感激。
先谢谢了。
答案 0 :(得分:2)
这是解决base R
中任务的解决方案,尽管-这里没有使用data.table
。
# logical vector with our condition tested
ind <- (diff(DF$CHR) == 0 & DF$KBdist[-1] < 5e+5)
# populating the 'locus' column --- notice the '<<-'
vapply(2:nrow(DF), function (k) DF$locus[k] <<- DF$locus[k-1] + 1 - ind[k-1], numeric(1))
# [1] 1 1 2 3 3
DF
# CHR SNP BP KBdist locus
# 1 1 rs2494631 2399149 NA 1
# 2 1 rs4648637 2401364 2215 1
# 3 1 rs2494627 2402499 1135 1
# 4 1 rs11122119 6768856 4366357 2
# 5 1 rs1844583 8383469 1614613 3
# 6 1 rs2292242 8385059 1590 3
vapply(...)
返回locus
柱并将其覆盖。
备注
请注意,我在函数内部使用了<<-
来覆盖DF$locus[k]
的值。如果您不喜欢这方面,只需将<<-
换成<-
,然后用vapply(...)
代替DF$locus[-1] <- vapply(...)
。
答案 1 :(得分:1)
另一种可能性是使用cumsum
:
setDT(DF)[, locus := cumsum(c(1L, (CHR!=shift(CHR,1L) | KBdist>=500e3)[-1L]))]
输出:
CHR SNP BP KBdist locus
1: 1 rs2494631 2399149 NA 1
2: 1 rs4648637 2401364 2215 1
3: 1 rs2494627 2402499 1135 1
4: 1 rs11122119 6768856 4366357 2
5: 1 rs1844583 8383469 1614613 3
6: 1 rs2292242 8385059 1590 3