前面那篇弄錯了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 的版本和套件版本資訊,
: 讓版友更容易找出錯誤
:
: [關鍵字]:
:
: 選擇性,也許未來有用
: