R:与第二个表合并更新表的高效方法来自相同列名的值填充NAs
总结:我想通过共享id键将两个表合并为all = true(全外连接),而不是具有相同名称的列被设置为var1.x var2.y等,它们被合并为单列其中左表中的缺失(NA)值由右侧表格中的值(除了合并的标准行为外,也就是附加具有不同名称的列和列的行)填充.
细节: 我想根据共享id键列将update table1与table2合并,以便: 1)如果table1和table2具有相同名称(id除外)的列,如果table1中的值为NA,则table1中的值如果存在并被table2中的值替换,则将其替换. 2)如果table2具有table1没有的列(不同的名称),则它们将被合并(按id). 3)如果table1具有与table2不匹配的id,则表2中不同名称列的值为NA 4)如果table2具有与table1不匹配的id,则作为新行添加,并且table1中不同列名的值为NA. 3& 4与标准合并与all = TRUE相同. 我担心我已经考虑了这个问题,因为我找不到一个直接的方式来做这个合并或联接,不涉及在每一列上创建ifelse检查.真正的数据有?1000列,所以要非常长的解决方案来进行ifelse查找. 可重现的简化示例: table1 <- data.table(id =c("id1","id2","id3","id4","id5","id6"),var1=c(1,2,3,4,5,6),var2=c("a","b",NA,"d","f"),var3=c(NA,12,13,14,15,16)); table2 <- data.table(id =c("id1","id8"),8),var2=c(NA,"c","e","h"),var4=c("foo","bar","oof","rab","sna")); desired <- data.table(id=c("id1","id6",6,"f",16,NA),"sna")); table1; id var1 var2 var3 1: id1 1 a NA 2: id2 2 b 12 3: id3 3 NA 13 4: id4 4 d 14 5: id5 5 e 15 6: id6 6 f 16 table2; id var1 var2 var4 1: id1 1 a foo 2: id2 2 b bar 3: id3 NA c oof 4: id4 4 d rab 5: id5 5 e NA 6: id8 8 h sna desired id var1 var2 var3 var4 1: id1 1 a NA foo 2: id2 2 b 12 bar 3: id3 3 c 13 oof 4: id4 4 d 14 rab 5: id5 5 e 15 NA 6: id6 6 f 16 NA 7: id8 8 h NA sna 所需输出的说明: >对于列var1,table1具有所有值,因此它被单独存在,并且table2中id3的NA被忽略(注意,这不包括下面描述的不同ID的行合并). 当然有一个直接的方法来做到这一点与data.table?鉴于实际数据的大小,高效的解决方案是特别受欢迎的. datamerge包显然是这样做的,但它不在CRAN上,我不能让它在zip上工作在R3.2.3上.有另一个包装加强了这项任务吗?还有许多其他线程专注于为已知名称的一列或两列进行解决,但对于大量的列,它们似乎不实用. 解决方法这是一种方法:com.cols = setdiff(intersect(names(table1),names(table2)),"id") com.cols.x = paste0(com.cols,".x") com.cols.y = paste0(com.cols,".y") # create combined table DT = setkey(merge(table1,table2,by="id",all=TRUE),NULL) # edit common columns where NAs are present for (j in seq_along(com.cols)) DT[is.na(get(com.cols.x[j])),(com.cols.x[j]) := get(com.cols.y[j])] # remove unneeded columns DT[,(com.cols.y) := NULL] # rename kept columns setnames(DT,com.cols.x,com.cols) identical(DT,desired) # TRUE 创建和使用所有这些列名称向量是相当凌乱的. 关于原来的问题… 这是另一种方式(没有从表2导入新行,如原始帖子): com.cols = setdiff(intersect(names(table1),"id") i.com.cols = paste0("i.",com.cols) new.cols = c(i.com.cols,setdiff(names(table2),c("id",com.cols))) # grab columns from table2 table1[table2,(new.cols) := mget(new.cols),on="id"] # edit common columns where NAs are present for (j in seq_along(com.cols)) table1[is.na(get(com.cols[j])),(com.cols[j]) := get(i.com.cols[j])] # remove unneeded columns table1[,(i.com.cols) := NULL] 这样,所有步骤都是通过引用对table1的修改. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |