簡體   English   中英

R:重新排序數據幀與組,同時保持組內的順序

[英]R: reorder a data frame with groups while preserving order within groups

R 編碼器,我有一個數據框plan ,有兩列。 一列有組標簽lab ,另一列tr只有兩個不同的值。

lab <- rep(letters[1:2], each = 4)
tr <- c(1, 2, 2, 1, 1, 2, 1, 2)
plan <- data.frame(lab = lab, tr = tr)

> plan
  lab tr
1   a  1
2   a  2
3   a  2
4   a  1
5   b  1
6   b  2
7   b  1
8   b  2

我有另一個向量order_new ,它是lab的重新排序版本。

order_new <- lab[sample(1:8)]

> order_new
[1] "b" "b" "a" "a" "b" "a" "b" "a"

我想重新排序上面的數據框,以便tr值按照order_new給出的順序排序,但保留原始lab組中的順序。 我想要的結果是:

plan_new <- data.frame(order_new = order_new, tr = c(1, 2, 1, 2, 1, 2, 2, 1))
 
> plan_new
  order_new tr
1         b  1
2         b  2
3         a  1
4         a  2
5         b  1
6         a  2
7         b  2
8         a  1

新數據框中的第一行是“b”值,因此采用原始數據框中的第一個“b”值。 第 2 行,也是一個“b”,取原來的第二個“b”值。 第三行,一個“a”,取原始等中的第一個“a”值。

我在過去的答案中找不到足夠接近的答案來解決這個問題,我真的很期待有人幫助我解決這個問題!

這是一個data.table方法.. 可以很容易地修改為 dplyr 或 baseR 解決方案,遵循相同的邏輯.. 我包括所有中間結果,向您展示每行的結果..

lab <- rep(letters[1:2], each = 4)
tr <- c(1, 2, 2, 1, 1, 2, 1, 2)
plan <- data.frame(lab = lab, tr = tr)
#hard coded, since sample is not reproducible without set.seed()
order_new <- c("b", "b", "a", "a", "b", "a", "b", "a")

library( data.table )
#make plan a data.table
setDT(plan)
#set row_id's by grope (lab)
plan[, row_id := rowid( lab ) ]
#    lab tr row_id
# 1:   a  1      1
# 2:   a  2      2
# 3:   a  2      3
# 4:   a  1      4
# 5:   b  1      1
# 6:   b  2      2
# 7:   b  1      3
# 8:   b  2      4

#make a new data.table for the new ordering
plan_new <- data.table( order_new = order_new )
#also add rownumbers by group
plan_new[, row_id := rowid( order_new ) ][]
#    order_new row_id
# 1:         b      1
# 2:         b      2
# 3:         a      1
# 4:         a      2
# 5:         b      3
# 6:         a      3
# 7:         b      4
# 8:         a      4

#now join the tr-value from data.table 'plan' to 'plkan2', based on the rowid
plan_new[ plan, tr := i.tr, on = .(order_new = lab, row_id) ]
#    order_new row_id tr
# 1:         b      1  1
# 2:         b      2  2
# 3:         a      1  1
# 4:         a      2  2
# 5:         b      3  1
# 6:         a      3  2
# 7:         b      4  2
# 8:         a      4  1

#drop the row_id column if needed
plan_new[, row_id := NULL ][]
#    order_new tr
# 1:         b  1
# 2:         b  2
# 3:         a  1
# 4:         a  2
# 5:         b  1
# 6:         a  2
# 7:         b  2
# 8:         a  1

如果你不介意循環

order_new=c("b", "b", "a", "a", "b", "a", "b", "a")

tmp=split(plan$tr,plan$lab)

res=list()
for (x in 1:length(order_new)) {
  res[[x]]=tmp[[order_new[x]]][1]
  tmp[[order_new[x]]]=tail(tmp[[order_new[x]]],-1)
}

data.frame(
  "lab"=order_new,
  "tr"=unlist(res)
)

  lab tr
1   b  1
2   b  2
3   a  1
4   a  2
5   b  1
6   a  2
7   b  2
8   a  1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM