我提到以下链接,似乎不适合我的问题。
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
答案 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))