2016-10-11 52 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 /列的循环。如果行数很多,不要在行上循环/应用,这会使代码变慢。 –

相关问题