2016-10-11 53 views
0

我會盡力解釋我正在做的最好的事情,但它可能會讓我感到困惑,但我會給它一個答案。本質上,我從2個數據框開始。每個人每個人包含一個唯一的行,每個用戶包含兩個列作爲列。我的目標是在條件不重複的情況下,將這個數據框變成1個數據框,每個用戶有一個唯一的行,並且來自兩個數據框中每一個的第一個條目。例如,如果對於第一個數據框中的客戶1,他的項目是「a」和「d」,並且在第二個數據框中他的項目是「a」和「c」,我希望最終的數據框架是「a」和「c」這個客戶。但是我寫了一個應用程序,但是當我在大約160,000行上執行此操作時,需要相當長的一段時間。我希望有人能夠爲我的問題提出更有效的解決方案。提取符合每行特定條件的第一列

d1 <- data.frame(id = c("1", "2", "3"), stringsAsFactors = F) 
r1 <- data.frame(i1 = c("a", "b", "c"), i2 = c("d", "e", "f"), stringsAsFactors = F) 
rownames(r1) = d1$id 
r2 <- data.frame(i1 = c("a", "c", "f"), i2 = c("c", "t", "l"), stringsAsFactors = F) 
rownames(r2) = d1$id 

dFinal <- data.frame(id = d1$id, r1 = "", r2 = "", stringsAsFactors = F) 

dFinal$r1 = apply(dFinal, 1, function(x){r1[rownames(r1) == x["id"], "i1"]}) 
dFinal$r2 = apply(dFinal, 1, function(x){r2[rownames(r2) == x["id"], which(!r2[rownames(r2) == x["id"],c("i1","i2")] %in% x["r1"])[1]]}) 
+0

嗯,我可以看到合併工作,但是我不確定合併的一部分將是如何選擇合併後的正確列。可以說,r1和r2的id是列而不是rownames。 'dInter < - merge(r1,r2,by =「id」)'但是我不知道如何從應用中複製邏輯,我只選擇了正確的列 – mikew

+0

在您的示例中,爲什麼* a *和* c *而不是* a *和* d *?還有其他標準嗎? – Parfait

+0

@Parfait我想從每個數據框中的前一個數據框中不存在的第一個可用列。因此,從第一個數據幀開始,選擇第一列_a_,然後對於第二個數據幀中的相同ID,選擇是_a_和_c_,因爲a已經用於第一個數據幀,則選擇_c_。 – mikew

回答

-1

感謝您接受的答案,因爲它w完美地完成了!但是它給了我一個使用ifelse的想法。雖然它沒有比接受的答案更好或更差,但是在添加更多列或數據框時,我更容易纏繞頭部。

dfInt <- cbind(df1, df2, df3, df4) 
    dfInt$R1_Final <- dfInt$R1_1 
    dfInt$R2_Final <- ifelse(dfInt$R1_Final == dfInt$R2_1, 
           dfInt$R2_2, 
           dfInt$R2_1) 
    dfInt$R3_Final <- ifelse(dfInt$R1_Final != dfInt$R3_1 & dfInt$R2_Final != dfInt$R3_1, 
           dfInt$R3_1, 
           ifelse(dfInt$R2_Final != dfInt$R3_2, 
             dfInt$R3_2, 
             dfInt$R3_3)) 
    dfInt$R4_Final <- ifelse(dfInt$R1_Final != dfInt$R4_1 & dfInt$R2_Final != dfInt$R4_1 & dfInt$R3_Final != dfInt$R4_1, 
           dfInt$R4_1, 
           ifelse(dfInt$R2_Final != dfInt$R4_2 & dfInt$R3_Final != dfInt$R4_2, 
             dfInt$R4_2, 
             ifelse(dfInt$R3_Final != dfInt$R4_3, 
              dfInt$R4_3, 
              dfInt$R4_4))) 
1

請問下面你在找什麼:

# Keep only first column of first data.frame 
df <- cbind(d1,r1,r2)[,-3] 
names(df) <- c("id","r1_final","r2_i1","r2_i2") 
df$r2_final <- df$r2_i1 

# Keep only second column of second data.frame 
# if the value in the first column is found in first data.frame 
df[df$r1_final == df$r2_i1,"r2_final"] <- df[df$r1_final == df$r2_i1,"r2_i2"] 
df_final <- df[,c("id","r1_final","r2_final")] 
print(df_final) 

    id r1_final r2_final 
1 1  a  c 
2 2  b  c 
3 3  c  f 

編輯: OP問一個解決方案,如果有四個data.frames,而不是像2在本例中,這裏是一些代碼,我沒有測試,但它應該與兩個額外的列

df$r2_final <- df$r2_i1 
df$r3_final <- df$r3_i1 
df$r4_final <- df$r4_i1 

df[df$r1_final == df$r2_i1,"r2_final"] <- df[df$r1_final == df$r2_i1,"r2_i2"] 
df[df$r3_i1 %in% c(df$r1_final,df$r2_final),"r3_final"] <- df[df$r3_i1 %in% c(df$r1_final,df$r2_final),"r3_i2"] 
df[df$r4_i1 %in% c(df$r1_final,df$r2_final,df$r3_final),"r4_final"] <- df[df$r4_i1 %in% c(df$r1_final,df$r2_final,df$r3_final),"r4_i2"] 
df_final <- df[,c("id","r1_final","r2_final","r3_final","r4_final")] 
+0

這可能是一個好主意!只編輯重複值的行。我確實認爲這解決了我發佈的問題,但如果你不介意問我,我會跟進一個。在實際問題中,我有4個r_final列,我試圖填充。我猜如果我只是擴展了你的答案,這將工作,但我不確定如果說我想讓r3_final不是等於r1_final和r2_final。 – mikew

+0

我添加了一個編輯,如果您有更多或可變數量的data.frames可以使用,那麼我會編寫一個函數,您可以在每個列數上使用它。我可以想象使用循環遍歷不同的data.frames /列的循環。如果行數很多,不要在行上循環/應用,這會使代碼變慢。 –

相關問題