2017-07-01 231 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 
相關問題