簡體   English   中英

按不同因素訂購數據框

[英]Ordering data frame by different factors

嗨,我有一個這樣的數據框:

x <- data.frame("Group"= c(rep(letters[1],2),rep(letters[2],2),rep(letters[3],2),rep(letters[4],2),letters[5]) , "Treatment"=   c(rep(c("ATR","Co"),4),"Gen"), "Mean" = 1:9)

我想做的是以自定義方式對其進行排序,即將“ Gen”處理的行移至第一行。 我可以用類似的東西找到它們:

if( "Genetic Control", idGroup$Treatment)
match("Genetic Control",idGroup$Treatment)
if(grepl("Gen",x$Treatment...

但是我找不到任何將上一行移到第一行的函數。 一旦我管理好了,我想通過每組兩個組件的x $ mean的平均值對其余數據進行排序。 例如,在這種情況下,“ d”的兩個分量的平均值為7.5,因此在“ Gen”處理之后,它將在接下來的行中顯示。 在此示例中,數據框應如下所示:

  x <- data.frame("Group"= c(letters[5], rep(letters[4],2),rep(letters[3],2),rep(letters[2],2),rep(letters[1],2)), "Treatment"=   c("Gen", rep(c("ATR","Co"),4)), "Mean" = 9:1)

這是使用R包sqldf的更新答案(單擊鏈接以獲得簡要介紹)。

library(sqldf)

x <- data.frame(
        "Group"= c(rep(letters[1],2),rep(letters[2],2),rep(letters[3],2),rep(letters[4],2),letters[5]), 
        "Treatment"=   c(rep(c("ATR","Co"),4),"Gen"), 
        "Mean" = 1:9)

首先,您可以使用此語句獲取每個組的平均值列的Mean (類似於R中的aggregate ):

sqldf("
SELECT 
    `Group` AS `Group`, 
    AVG(`Mean`) AS `GroupMean` 
FROM x 
GROUP BY `Group`;")

  Group GroupMean
1     a       1.5
2     b       3.5
3     c       5.5
4     d       7.5
5     e       9.0

然后是使用JOIN語句(如R中的merge )將此表連接到原始表的情況,將'Gen'放在頂部,然后按GroupMean排序。 我將這些表稱為t1t2 ,將它們連接在一起,然后從中選擇所需的列並對表進行排序。 我已經格式化了查詢,因此希望它更容易理解。 閱讀有關MySQLsqldf的幾篇文章應該會有所幫助。 另外,根據@G的評論。 對於Grothendieck,您可以使用`括起列名,使用'括起字符串。 希望這可以幫助。

sqldf("
SELECT 
    t1.`Group` AS `Group`, 
    t1.`Treatment` AS `Treatment`, 
    t1.`Mean` AS `Mean`, 
    t2.`GroupMean` AS `GroupMean` 
FROM
    (SELECT * FROM x) t1
    JOIN
    (SELECT 
        `Group` AS `Group`, 
        AVG(`Mean`) AS `GroupMean` 
    FROM x 
    GROUP BY `Group`) t2
    ON t1.`Group` = t2.`Group`
ORDER BY CASE `Treatment` WHEN 'Gen' THEN 1 ELSE 2 END, 
    `GroupMean` DESC, 
    `Mean` DESC;
")

  Group Treatment Mean GroupMean
1     e       Gen    9       9.0
2     d        Co    8       7.5
3     d       ATR    7       7.5
4     c        Co    6       5.5
5     c       ATR    5       5.5
6     b        Co    4       3.5
7     b       ATR    3       3.5
8     a        Co    2       1.5
9     a       ATR    1       1.5

嘗試這個

x$Treatment <- ordered(x$Treatment, levels = c("Gen", "ATR", "Co")) 
x <- x[order(x$Treatment), ]

按照所需順序定義levels 。使用unique(x$Treatment)查看處理方式。

對於您問題的第二部分,我不確定我是否理解。 試試這個,讓我知道它是否有效:

library(dplyr)

x$rank <- (x$Treatment!="Gen")*1
x <- x %>% group_by(Group) %>% mutate(temp=mean(Mean)) %>% 
      ungroup %>% arrange(rank, -temp) %>% select(-rank, -temp)

暫無
暫無

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

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