2017-07-01 143 views
0

我有两个数据帧。第一个包含一个包含ID和各种其他列的列,而另一个包含这些ID(ID到名称)的映射信息。匹配数据帧之间的行并将其替换为第二个数据帧中另一列中的值

我想用另一个数据框中的名称替换第一个数据帧中的ID。

我能够做到这一点

for(id in 1:nrow(df1)){ 
    df1$X[df1$X %in% df2$ID[id]] <- df2$Name[id] 
} 

这工作,只要我没有在映射文件中重复的ID,如本:

ID,Name 
MSTRG.11187,gng7.S 
MSTRG.11187,Novel 

但这样的情况不少。我认为我以前的代码将工作,如果我可以摆脱映射文件中包含单词Novel的任何行。我只是在努力做到这一点。我曾经尝试这样做:

data = data %>% group_by(GeneID) %>% filter(!("Novel" %in% Gene_Name)) 

但具有不同名称的重复的ID前面的例子,它就会与gng7.S摆脱行以及与小说摆脱了行。我想这样做,但保持与gng7.S行,只有摆脱与小说行。

我在想这可能与group_by部分有关。

感谢,
小号

编辑:下面是一些例子dataframes

df1=data.frame(X=c("MSTRG.199","MSTRG.18989","MSTRG.8890","MSTRG.7767")) 

df2=data.frame(ID=c("MSTRG.18989","MSTRG.18989","MSTRG.8890","MSTRG.7767", "MSTRG.199"),Name=c("gng7.S", "Novel", "Novel","cdc20", "Novel")) 
+2

请提供一个可重现的数据示例。有可能你可以在R中使用一些连接操作来避免for循环。 – www

+0

data = data%>%group_by(Name)%>%filter(!(“Novel”%in%Gene_Name)) 这似乎是做映射文件的技巧,for循环正在工作,但它正在很长时间。 (文件长度为60k +行)。 –

回答

0

问题不完全清楚是否"Novel"任何出场应该从df2被移除或仅在重复ID案件。第二种情况是相当棘手,所以我提出一个data.table解决方案,我更流利(和Q没有明确地标记为dplyr

df1 <- data.frame(X = c("MSTRG.199", "MSTRG.18989", "MSTRG.8890", "MSTRG.7767")) 
df2 <- data.frame(
    ID = c("MSTRG.18989", "MSTRG.18989", "MSTRG.8890", "MSTRG.7767", "MSTRG.199"), 
    Name = c("gng7.S", "Novel", "Novel", "cdc20", "Novel")) 

library(data.table) 
DT1 <- data.table(df1) 
DT2 <- data.table(df2) 

# case 1 
# remove all rows with Name == Novel before joining 
DT2[!Name %in% c("Novel")][DT1, on = .(ID = X)] 
  ID Name N 
1: MSTRG.199  NA NA 
2: MSTRG.18989 gng7.S 2 
3: MSTRG.8890  NA NA 
4: MSTRG.7767 cdc20 1 
# case 2 
# remove Novel in cases of duplicate appearances of ID 
DT2[, N := .N, by = ID][!(N > 1L & Name %in% "Novel")][, N := NULL][DT1, on = .(ID = X)] 
  ID Name 
1: MSTRG.199 Novel 
2: MSTRG.18989 gng7.S 
3: MSTRG.8890 Novel 
4: MSTRG.7767 cdc20 
相关问题