问题描述
我有2个数据集,我想为datset1中的每一行计算另一个数据集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,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