在R中基于两列“字符”类型的内容删除重复行

3
我有一个数据框,想要删除那些在两列中都有重复字符串的行(分别命名为“Up”和“Down”)。如果某些行只在其中1个列中具有重复的字符串,则不应将它们删除。 从重复的行中,我希望保留另一列(名为“Fold”)中找到的最高值所在的行。除此任务之外,第四列(名为“Name”)还需要进行以下字符替换:

从这个开始:

ID  Name                    Fold   Up           Down
1   mRNA_splicing(5)        3.2    a,b,c,d,e    f,g,h,i 
2   mRNA_processing(7)      3.1    a,b,c,d,e    f,g,h,i 
3   adherens_junctions(5)   2.6    k,l,m        p,q,r,s,t,u
4   glucose_transport(4)    3.4    d,j,n        o,p,v,w,z              
5   hexose_transport(2)     3.5    d,j,n        o,p,v,w,y,z

我希望获得这个:

ID  Name                    Fold   Up           Down
1   mRNA splicing           3.2    a,b,c,d,e    f,g,h,i  
2   adherens junctions      2.6    k,l,m        p,q,r,s,t,u
3   glucose transport       3.4    d,j,n        o,p,v,w,z              
4   hexose transport        3.5    d,j,n        o,p,v,w,y,z

关于执行去重行的函数,对于字符而言,duplicateunique均无法正常工作,那么此处该怎么办呢?欢迎提供您优雅的解决方案。

3个回答

2
使用数据表解决方案:
dt <- as.data.table(your_df)
dt <- dt[dt[, .I[Fold == max(Fold)], by=list(Up, Down)]$V1]
dt[["Name"]] <- gsub("_", " ", sub("\\(.*?\\)$", "", dt[["Name"]]))
dt

   ID               Name Fold        Up        Down
1:  1      mRNA splicing  3.2 a,b,c,d,e     f,g,h,i
2:  3 adherens junctions  2.6     k,l,m p,q,r,s,t,u
3:  4  glucose transport  3.4     d,j,n   o,p,v,w,z
4:  5   hexose transport  3.5     d,j,n o,p,v,w,y,z

2
一种使用基础R语言的解决方案:
df <- df[order(df$Fold, decreasing = TRUE),]
df <- df[!(duplicated(df$Up) & duplicated(df$Down)),]
df$Name <- gsub("_", " ", gsub('.{0,3}$', '', df$Name))
df <- df[order(df$ID),]

数据

df <- read.table(text = "
ID  Name                    Fold   Up           Down
1   mRNA_splicing(5)        3.2    a,b,c,d,e    f,g,h,i 
                 2   mRNA_processing(7)      3.1    a,b,c,d,e    f,g,h,i 
                 3   adherens_junctions(5)   2.6    k,l,m        p,q,r,s,t,u
                 4   glucose_transport(4)    3.4    d,j,n        o,p,v,w,z              
                 5   hexose_transport(2)     3.5    d,j,n        o,p,v,w,y,z
                 ", header = TRUE)

df$Name <- as.character(df$Name)

输出

   ID           Name    Fold        Up        Down
1  1      mRNA splicing  3.2 a,b,c,d,e     f,g,h,i
3  3 adherens junctions  2.6     k,l,m p,q,r,s,t,u
4  4  glucose transport  3.4     d,j,n   o,p,v,w,z
5  5   hexose transport  3.5     d,j,n o,p,v,w,y,z

0
使用 dplyr + stringr编辑以包含 tmfmnk 的建议):
df %>% 
    group_by(Up, Down) %>% 
    slice(which.max(Fold)) %>% 
    mutate(Name = str_remove(Name, "\\(.*?\\)"))

输出:

# A tibble: 4 x 5
# Groups:   Up, Down [4]
     ID Name                Fold Up        Down       
  <int> <chr>              <dbl> <chr>     <chr>      
1     1 mRNA_splicing        3.2 a,b,c,d,e f,g,h,i    
2     5 hexose_transport     3.5 d,j,n     o,p,v,w,y,z
3     4 glucose_transport    3.4 d,j,n     o,p,v,w,z  
4     3 adherens_junctions   2.6 k,l,m     p,q,r,s,t,u

1
或者只需使用 df %>% group_by(Up, Down) %>% slice(which.max(Fold)) - tmfmnk
好的,@tmfmnk,我已经添加了你的版本。 - user10191355

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接