利用相似数据帧的内容提高更新大数据帧内容的性能

gka*_*pas 6 r dataframe data.table

我正在寻找一个通用的解决方案来更新一个大数据帧与第二个类似数据帧的内容.我有几十个数据集,每个数据集有数千行,超过10,000列."更新"数据集将与其对应的"基础"数据集重叠,从几个百分点到大约百分之五十,行方向.数据集具有"键"列,并且在任何给定数据集中每个唯一键值只有一行.

基本规则是:如果给定单元格的更新数据集中存在非NA值,则使用该值替换基础数据集中的相同单元格.("相同单元格"表示"key"列和colname的相同值.)

请注意,更新数据集可能包含我可以使用rbind处理的新行("插入").

因此,给定基础数据框"df1",其中列"K"是唯一键列,"P1"."P3"代表10,000列,其名称将从一对数据集到下一个数据集变化:

  K P1 P2 P3
1 A  1  1  1
2 B  1  1  1
3 C  1  1  1
Run Code Online (Sandbox Code Playgroud)

...和更新数据框"df2":

  K P1 P2 P3
1 B  2 NA  2
2 C NA  2  2
3 D  2  2  2
Run Code Online (Sandbox Code Playgroud)

我需要的结果如下,其中"B"和"C"的1被2覆盖,但没有被NA覆盖:

  K P1 P2 P3
1 A  1  1  1
2 B  2  1  2
3 C  1  2  2
4 D  2  2  2
Run Code Online (Sandbox Code Playgroud)

这似乎不是合并候选者,因为合并给我重复行(相对于"关键"列)或重复列(例如P1.x,P1.y),我必须迭代以折叠某种方式.

我已经尝试预先分配一个矩阵,其中包含最终行/列的维度,并用df1的内容填充它,然后迭代df2的重叠行,但我不能比每秒20个单元格的性能更好,需要几小时完成(与SAS中等效的DATA step UPDATE功能的分钟数相比).

我确定我错过了什么,但找不到类似的例子.

我看到ddply用法看起来很接近,但不是一般的解决方案.该data.table软件包似乎没有帮助,因为对我来说这是一个连接问题并不明显,至少通常没有这么多列.

另外一个只关注交叉行的解决方案就足够了,因为我可以识别其他行并将其绑定.

以下是制作上述数据框的一些代码:

cat("K,P1,P2,P3", "A,1,1,1", "B,1,1,1", "C,1,1,1", file="f1.dat", sep="\n");
cat("K,P1,P2,P3", "B,2,,2", "C,,2,2", "D,2,2,2", file="f2.dat", sep="\n");
df1 <- read.table("f1.dat", sep=",", header=TRUE, stringsAsFactors=FALSE);
df2 <- read.table("f2.dat", sep=",", header=TRUE, stringsAsFactors=FALSE);
Run Code Online (Sandbox Code Playgroud)

谢谢

Mat*_*wle 2

这按列循环,dt1通过引用设置并且(希望)应该很快。

dt1 = as.data.table(df1)
dt2 = as.data.table(df2)
if (!identical(names(dt1),names(dt2)))
    stop("Assumed for now. Can relax later if needed.")
w = chmatch(dt2$K, dt1$K)
for (i in 2:ncol(dt2)) {
    nna = !is.na(dt2[[i]])
    set(dt1,w[nna],i,dt2[[i]][nna])
}
dt1 = rbind(dt1,dt2[is.na(w)])
dt1
     K P1 P2 P3
[1,] A  1  1  1
[2,] B  2  1  2
[3,] C  1  2  2
[4,] D  2  2  2
Run Code Online (Sandbox Code Playgroud)