[問題] 階層資料列轉欄

作者: criky (2501-2)   2016-12-20 08:14:51
[問題類型]:
程式諮詢(我想用R 做某件事情,但是我不知道要怎麼用R 寫出來)
[軟體熟悉度]:
新手(沒寫過程式,R 是我的第一次)
[問題敘述]:
資料如下:
id LV Obj Dep
1 0 A1
2 1 A1 A1
2 2 B1 A1
3 1 A1 A1
3 2 B2 A1
3 3 C1 B2
4 1 A1 A1
4 2 B2 A1
4 3 C2 B2
4 4 D1 C2
想將資料轉成以下方式:
id Obj Dep1 Dep2 Dep3 Dep4
1 A1 A1
2 A1 A1 B1
3 A1 A1 B2 C1
4 A1 A1 B2 C2 D1
空格可以填NA或留空都可,
階層數不一定,最小0,最大30
同一個Obj可能有許多階層的關係~
再請教大家了,謝謝
[關鍵字]:
level
自己查版上文章看推文,將主要部分試出來了,
dt_list<-tapply(dt$Obj,dt$id,c)
$`1`
[1] "A1"
$`2`
[1] "A1" "B1"
$`3`
[1] "A1" "B2" "C1"
$`4`
[1] "A1" "B2" "C2" "D1"
本來想用 do.call(rbind,.) 但有空格處會以重覆值填補
若用as.data.frame將list轉df,
則是只有1個變數,還要再分割處理
後來發現tapply只看obj及id,
但真實data可能連id都要自己作出來,
其實還是有點難度 @@
感謝cy大提供解法如下:
library(data.table)
library(magrittr)
dt <- fread('LV Obj Dep
0 A1 ""
1 A1 A1
2 B1 A1
1 A1 A1
2 B2 A1
3 C1 B2
1 A1 A1
2 B2 A1
3 C2 B2
4 D1 C2')
dt[,stx:=ifelse(LV<1,"Dep1",paste0("Dep",LV)),by=.(LV)] %>%
.[,nL:=as.integer(stx=="Dep1")] %>%
.[,ngp:=cumsum(nL)]
x1 <- dcast(dt, ngp ~ stx, value.var = "Obj")
正是我要的結果!
不過我再回去看資料發現我舉例有誤 XD
我的資料及修改cy大的程式碼如下:
dt <- fread('LV Obj Dep
0 A1 ""
1 B1 A1
0 A1 ""
1 B2 A1
2 C1 B2
0 A1 ""
1 B2 A1
2 C2 B2
3 D1 C2')
#0階是底層
dt[,stx:=ifelse(LV<1,"Dep0",paste0("Dep",LV)),by=.(LV)] %>%
#加入stx欄,底層命名為Dep0,其它為Dep+LV
.[,nL:=as.integer(stx=="Dep0")] %>%
#加入nL欄,stx==Dep0為1,其它為0
.[,ngp:=cumsum(nL)]
#加入ngp欄==nL累積次數
x1 <- dcast(dt, ngp ~ stx, value.var = "Obj")
x1
ngp Dep0 Dep1 Dep2 Dep3
1: 1 A1 B1 NA NA
2: 2 A1 B2 C1 NA
3: 3 A1 B2 C2 D1
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 27.147.47.152
※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1482192894.A.068.html
作者: abc2090614 (casperxdd)   2016-12-20 09:34:00
這等於是有個tree的edges + depths 然後作 root toleaf tree traversal?...我其實也滿好奇這在r要怎作
作者: clansoda (小笨)   2016-12-20 09:55:00
認真的說 樓上的大大真是厲害 我看不懂怎麼從圖一變圖二的 本來想解 結果看不懂XD
作者: cywhale (cywhale)   2016-12-22 00:47:00
你的意思是id是自己手動加的?所以要能自動產生?..
作者: criky (2501-2)   2016-12-22 07:26:00
yes 我剛po文時是沒有id的,資料也沒有id,只有階層關係

Links booklink

Contact Us: admin [ a t ] ucptt.com