2013-09-30 38 views
0

我有两个表格:df.authordf.post,它们通过一对多关系相关。现在我更改了主键df.author,并且我想要df.post来镜像更改。在下列R-脚本我用match()while循环与df.author的旧的主键来比较每一行的外键df.post和当他们与新的匹配替换外键一个(形成不同的列df.author)。请考虑以下几点:比较两个向量一次一个值而不使用WHILE

foreignkey <- c("old_pk1","old_pk2","old_pk3","old_pk4","old_pk5","old_pk1","old_pk7") 
df.post <- data.frame(foreignkey,stringsAsFactors=FALSE) 
rm(foreignkey) 

primarykey_old <- c("old_pk1","old_pk2","old_pk3","old_pk4","old_pk5") 
primarykey_new <- c("new_pk1","new_pk2","new_pk3","new_pk4","new_pk5") 
df.author <- data.frame(primarykey_old, primarykey_new, stringsAsFactors=FALSE); 
rm(primarykey_old); rm(primarykey_new) 

i <- 1; N <- length(df.post$foreignkey) 
while (i <= N) { 
    match <- match(df.post$foreignkey[i], df.author$primarykey_old) 
    if (!is.na(match)) { 
    df.post$foreignkey[i] <- df.author$primarykey_new[match] 
    } 
    i <- i + 1 
} 
rm(N); rm(i); rm(match) 

脚本工作,但由于while不适合大数据集高效扩展。我读过使用apply()(在我的情况下通过转换为矩阵)通常比使用while更好。我想知道这是否也适用于我的情况。因为如果你看看你看到的循环,我需要遍历数据帧的每一行以获取外键,然后通过df.author获得match()。 我可以通过不使用while来压缩计算时间吗?

+0

这是拼写错误:'as.Character'。如果这确实存在一个多种可能性的问题,那么您可以构建一个展示该特征的数据集 –

+0

对不起,该行由'stringsAsFactors = FALSE'冗余' – CptNemo

+0

第二个问题仍未解决。我怀疑它使我所给的答案无效,但现在您有责任构建一个反例。 –

回答

1

我认为这可能会在无回路的方式做的一切:

df.post$foreignkey[ 
    !length(match(df.post$foreignkey, df.author$primarykey_old))==0] <- # the test 
    df.author$primarykey_new[match(df.post$foreignkey, df.author$primarykey_old)] 

逻辑:只有当存在一个匹配,那么替换匹配的值的现有价值。

+0

如果我理解正确'match()'只返回第一个匹配。那么,如果'df.post $ foreignkey'中有重复的值,这里会发生什么? (这是从'df.post'到'df.author'的多对一关系)。我可以检查它确实有效,我只是不明白如何...... – CptNemo

+0

我编辑了我的问题,以增加'foreignkey'中'primarykey_old'中不存在的值的情况。通过这个解决方案,'foreignkey'中的不匹配值被替换为空值。是否可以修改'foreignkey'中的值以便匹配? – CptNemo