前面那篇弄错了XD
我写一次正确板出来QQ
library(data.table)
library(pipeR)
DT <- fread("id start_y start_s end_y end_s
1 100 1 102 2
2 101 2 103 1
3 101 2 101 2")
DT[ , `:=`(start_ys = paste(start_y, start_s, sep = "-"),
end_ys = paste(end_y, end_s, sep = "-"))]
lookup_dt <- expand.grid(min(DT$start_y):max(DT$end_y), 1:2) %>>%
data.table %>>% `[`(j = y_s := paste(Var1, Var2, sep = "-"))
# lookup_dt <- CJ(min(DT$start_y):max(DT$end_y), 1:2) %>>%
# `[`(j = y_s := paste(V1, V2, sep = "-")) # 这样做是一样的
outDT <- DT[ , .(out_ys = lookup_dt$y_s[between(lookup_dt$y_s, start_ys,
end_ys)]), by = .(id)] %>>%
`[`(j = c("year", "s") := tstrsplit(out_ys, "-")) %>>%
`[`(j = out_ys := NULL)
# id year s
# 1: 1 100 1
# 2: 1 100 2
# 3: 1 101 1
# 4: 1 101 2
# 5: 1 102 1
# 6: 1 102 2
# 7: 2 101 2
# 8: 2 102 1
# 9: 2 102 2
# 10: 2 103 1
# 11: 3 101 2
# 改成下面这样比较易懂:
all_ys <- expand.grid(min(DT$start_y):max(DT$end_y), 1:2) %>>%
with(paste(Var1, Var2, sep = "-"))
outDT <- DT[ , .(out_ys = all_ys[between(all_ys, start_ys,
end_ys)]), by = .(id)] %>>%
`[`(j = c("year", "s") := tstrsplit(out_ys, "-")) %>>%
`[`(j = out_ys := NULL)
这方法只适用data.table,data.table的between才可以比字串XD
如果出现Error: not compatible with requested type
代表说你的between不是用data.table的,所以会出问题
这时候请用 detach("package:dplyr", unload=TRUE)
如果还是不行就要看你的between是用到哪一个package
或是 干脆在between前面加上 data.table::即可
※ 引述《criky (立业成家)》之铭言:
: [问题类型]:
:
: 程式咨询(我想用R 做某件事情,但是我不知道要怎么用R 写出来)
: [软件熟悉度]:
: 新手(没写过程式,R 是我的第一次)
: [问题叙述]:
: 若我有资料字段如下:
:
: id start_y start_s end_y end_s
: 1 100 1 102 2
: 2 101 2 103 1
: 3 101 2 101 2
: year:
: 如何转成下面的样子:
: id year s
: 1 100 1
: 1 100 2
: 1 101 1
: 1 101 2
: 1 102 1
: 1 102 2
: 2 101 2
: 2 102 1
: 2 102 2
: 2 103 1
: 3 101 2 (只有一笔)
: 谢谢回答~
: [程式范例]:
:
:
: [环境叙述]:
:
: 请提供 sessionInfo() 的输出结果,
: 里面含有所有你使用的作业系统、R 的版本和套件版本资讯,
: 让版友更容易找出错误
:
: [关键字]:
:
: 选择性,也许未来有用
: