计算数据集中的一行与R中另一个数据集中的所有行之间的差异

Calculate the difference between a row in a dataset and all rows in another dataset in R

我有 2 个数据集,我想为数据集 1 中的每一行计算另一个数据集 2 中所有行之间的差异。我还将任何负差异替换为 0。这是我的 2 个数据集的一个简单示例(因为我有大约 1000*1000 的数据集)。

df1 <- data.frame(ID = c(1, 2), Obs = c(1.0, 2.0), var=c(2.0,5.0))
df2 <- data.frame(ID = c(2, 1), Obs = c(3.0, 2.0),var=c(7.0,3.0))

 df1
  ID Obs var
1  1   1   2
2  2   2   5

 df2
  ID Obs var
1  2   3   7
2  1   2   3


for(i in 1:nrow(df1)){
  b1=as.matrix(df1)
  b2=as.matrix(df2)
  diff= b1-b2
  diff[which(diff < 0 )] <- 0
 
  diff.data= data.frame(cbind(diff, total = rowSums(diff)))
 
}

 diff.data
  ID Obs var total
1  0   0   0     0
2  1   0   2     3

这就是我能够做到的,我做了 2 个数据集之间的差异,将负值替换为 0,并且也有兴趣对之后的列值求和。对于 df1 中的第一行,我想计算 df2 中所有行之间的差异,对于 df1 中的第二行,我想计算 df2 中所有行之间的差异(依此类推)。请注意,我不应该计算 ID 之间的差异(我不知道该怎么做,也许将 diff= b1-b2 更改为 diff= b1[,-1]-b2[,-1]?)。我想保留 df1 的 ID 以跟踪我的患者(我的数据集的情况)。我想要这样的东西

diff.data
ID Obs var total
1  0   0   0
1  0   0   0
2  0   0   0
2  0   2   2

在此先感谢您的帮助。

这是我使用您的答案得到的结果,我想创建一个简单的函数。但我希望我的数据集可以是矩阵或数据帧,如果数据集不是数据帧,我只能生成错误:

difference=function(df1,df2){
  if(class(df1) != "data.frame" || class(df2) != "data.frame") stop(" df1 or df2 is not  a dataframe!")
  df1=data.frame(df1)
  df2=data.frame(df2)
  ID1=seq(nrow(df1))
  ID2=seq(nrow(df2))
  new_df1 = df1[rep(ID1, each = nrow(df2)), ]
  new_df1[-1] = new_df1[-1] - df2[rep(seq(nrow(df2)), nrow(df1)), -1]
  new_df1[new_df1 < 0] = 0
  new_df1$total = rowSums(new_df1[-1])
  rownames(new_df1) = NULL
  output=new_df1
  return(output)
  
}

我知道我指定的 df1=data.frame(df1) 必须是一个数据框,只是我不知道如何包含它可能是一个矩阵。

再次感谢您的帮助。

您可以将 df1 中的每一行重复 nrow(df2) 次,将 df2 中的每一行重复 nrow(df1) 次,以便数据帧的大小相等,我们可以直接减去数值。

#Repeat each row of df1 nrow(df2) times
new_df1 <- df1[rep(df1$ID, each = nrow(df2)), ]
#Repeat rows of df2 and subtract
new_df1[-1] <- new_df1[-1] - df2[rep(seq(nrow(df2)), nrow(df1)), -1]
#Replace negative values with 0
new_df1[new_df1 < 0] <- 0
#Add row-wise sum
new_df1$total <- rowSums(new_df1[-1])
#Remove rownames
rownames(new_df1) <- NULL
new_df1

#  ID Obs var total
#1  1   0   0     0
#2  1   0   0     0
#3  2   0   0     0
#4  2   0   2     2