如何根据三个因素级别删除重复行

时间:2015-02-27 11:06:03

标签: r

我提到以下链接,似乎不适合我的问题。

Remove rows based on factor-levels

Remove row based on two factor levels

我的数据框如下所示。

  ZNF226  1  A
  ZNF226  1  P
  ZNF227  1  M
  ZNF227  1  P
  ZNF229  1  P
  ZNF229  1  A
   ZNF23  1  M
  ZNF230  1  A
  ZNF232  1  P
  ZNF233  1  A
  ZNF233  1  P
  ZNF234  1  P
  ZNF235  1  A
  ZNF236  1  P
  ZNF236  1  P
  ZNF238  1  A
  ZNF238  1  M
  ZNF239  1  P
   ZNF24  1  A
   ZNF24  1  P
   ZNF24  1  P
   ZNF24  1  P

我想删除重复的行。我想在第三列中保留优先于P> A> M的行。如果行具有P,A,M,则仅保留具有P的行。如果A和M然后A将在那里删除其他重复项,最后是M.预期输出低于

  ZNF226  1  P
  ZNF227  1  P
  ZNF229  1  P
   ZNF23  1  M
  ZNF230  1  A
  ZNF232  1  P
  ZNF233  1  P
  ZNF234  1  P
  ZNF235  1  A
  ZNF236  1  P
  ZNF238  1  A
  ZNF239  1  P
   ZNF24  1  P

行数约为70k。提前谢谢。

编辑:第一行和第二行之上是重复的。第一行的第三行有A,第三行的第二行有P。正如我所提到的,偏好将是P>A>M。所以A在P. So后面有第二个偏好A

现在排在第3和第4行。 P首先要保留M

2 个答案:

答案 0 :(得分:1)

将1,2,3分配给M,A,P,例如:

df$x[df$col3 == "M"] <- 1
df$x[df$col3 == "A"] <- 2
df$x[df$col3 == "P"] <- 3

然后按第1列和第2列使用聚合

df <- aggregate(df$x, list(df$col1, df$col2), max)

然后将数字还原为相应的字母。

您提供的示例,粗略的读入:

df <- read.table(text = "
ZNF226  1  A
ZNF226  1  P
ZNF227  1  M
ZNF227  1  P
ZNF229  1  P
ZNF229  1  A
ZNF23  1  M
ZNF230  1  A
ZNF232  1  P
ZNF233  1  A
ZNF233  1  P
ZNF234  1  P
ZNF235  1  A
ZNF236  1  P
ZNF236  1  P
ZNF238  1  A
ZNF238  1  M
ZNF239  1  P
ZNF24  1  A
ZNF24  1  P
ZNF24  1  P
ZNF24  1  P", sep = " ", header = F)

df <- df[-c(2,4)]
colnames(df) <- c("col1", "col2", "col3")

df$x[df$col3 == "M"] <- 1
df$x[df$col3 == "A"] <- 2
df$x[df$col3 == "P"] <- 3

df <- aggregate(df$x, list(df$col1, df$col2), max)
colnames(df) <- c("col1", "col2", "col3")

df$col3[df$col3 == 1] <- "M"
df$col3[df$col3 == 2] <- "A"
df$col3[df$col3 == 3] <- "P"

输出:

> df
     col1 col2 col3
1  ZNF226    1    P
2  ZNF227    1    P
3  ZNF229    1    P
4   ZNF23    1    M
5  ZNF230    1    A
6  ZNF232    1    P
7  ZNF233    1    P
8  ZNF234    1    P
9  ZNF235    1    A
10 ZNF236    1    P
11 ZNF238    1    A
12 ZNF239    1    P
13  ZNF24    1    P
> 

答案 1 :(得分:1)

我们可以将data.table用于大数据集。将“data.frame”转换为“data.table”(setDT(df1))。通过“V1”和“V2”分组,通过基于偏好指定级别(“P> A> M”)将“V3”的类别改变为因子。获取“V3”(which.min)的“最小”值索引和“V3”(V3[which.min(..)]

的子集
library(data.table)
setDT(df1)[, list(V3=V3[which.min(factor(V3, levels=c('P', 'A', 'M')))]),
                                   .(V1, V2)]
 #       V1 V2 V3
 #1: ZNF226  1  P
 #2: ZNF227  1  P
 #3: ZNF229  1  P
 #4:  ZNF23  1  M
 #5: ZNF230  1  A
 #6: ZNF232  1  P
 #7: ZNF233  1  P
 #8: ZNF234  1  P
 #9: ZNF235  1  A
#10: ZNF236  1  P
#11: ZNF238  1  A
#12: ZNF239  1  P
#13:  ZNF24  1  P

或使用dplyr

的类似方法
library(dplyr)
 df1 %>% 
    group_by(V1, V2) %>% 
    summarise(V3=V3[which.min(factor(V3, levels=c('P', 'A', 'M')))])

更新

基于新数据集

df2 <- read.csv('111.csv', header=TRUE, stringsAsFactors=FALSE)
str(df2)
#'data.frame':  2618 obs. of  4 variables:
# $ X : int  1 2 3 4 5 6 7 8 9 10 ...
# $ V1: chr  "A1BG" "A1BG-AS" "A1CF" "A2LD1" ...
# $ V2: int  1 1 1 1 1 1 1 1 1 1 ...
# $ V3: chr  "P" "A" "A" "A" ...
res <-  setDT(df2)[, list(V3=V3[which.min(factor(V3,
           levels=c('P', 'A', 'M')))]), .(V1, V2)]
dim(res)
#[1] 1175    3

如果我们需要在R控制台中打印所有数据集行,请更改options

  op <- options(datatable.print.nrows=Inf)
  res[1:10,]

数据

df1 <- structure(list(V1 = c("ZNF226", "ZNF226", "ZNF227", "ZNF227", 
"ZNF229", "ZNF229", "ZNF23", "ZNF230", "ZNF232", "ZNF233", "ZNF233", 
"ZNF234", "ZNF235", "ZNF236", "ZNF236", "ZNF238", "ZNF238", "ZNF239", 
"ZNF24", "ZNF24", "ZNF24", "ZNF24"), V2 = c(1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), V3 = c("A", "P", "M", "P", "P", "A", "M", "A", "P", "A", 
"P", "P", "A", "P", "P", "A", "M", "P", "A", "P", "P", "P")),
.Names =  c("V1", "V2", "V3"), class = "data.frame", 
row.names = c(NA, -22L))