我想优化我的代码,因为使用循环需要太长时间。我在下面准备了一个问题方案。
我想比较两个数据帧的第2和第3列中的值。 因此,我希望在比较满足要求的两个数据帧后得到一个表:
如果第一个数据框中第2列的值(df)> =第二个数据框中第2列中的值(df2)和df中第3列中的值< = df2中3r列中的值
所以我的要求:
if(df [i,2]> = df2 [j,2]&& df [i,3]< = df2 [j,3])
下面我的代码效果很好并且做了我想要的但是我认为它效率不高。有没有人知道我可以用来改进(加速)我的代码的功能?
#data frames
L1 = c(65, 61, 70, 65)
L2 = c(150, 135, 210, 140)
Name= c("A","A","A","A")
df = data.frame(Name, L1, L2)
L12 = c(70, 63, 52, 65)
L22 = c(132, 135, 145, 150)
Name2 = c("B","B","B","B")
df2 = data.frame(Name2, L12, L22)
temp <- df[FALSE,]
temp1 <- df2[FALSE,]
for (i in 1:nrow(df)){
l = 1
for (j in 1:nrow(df2)){
if(df[i,2] >= df2[j,2] && df[i,3] <= df2[j,3]){
temp[l,] <-df[i,]
temp1[l,] <-df2[j,]
l = l + 1
}
}
summ <- cbind(temp, temp1)
if(i==1){
sum1 <- summ
}
else(sum1 <- rbind(sum1,summ))
temp <- temp[FALSE,]
temp1 <- temp1[FALSE,]
}
此外,我必须逐个比较每个数据帧。我认为最简单的方法是将所有数据框作为列表读取并使用一些功能 - 也许来自申请系列?我试着这样做,但我失败了。我将不胜感激任何提示:)
答案 0 :(得分:2)
和其他人一样,我并不完全确定我理解你想要什么。我想这就是你追求的目标?
lapply(1:nrow(df),function(X)
df[X,1]>=df2[,2]&&df[X,1]<df2[,3]
)
这将返回df中每行的列表,即逻辑测试为真的实例数
lapply(1:nrow(df),function(X)
sum(df[X,1]>=df2[,2]&&df[X,1]<df2[,3])
)
此外,您的代码包含一些基本的低效语句(例如,增长数据) - 这对于处理大数据时的速度可能是有害的。然而,有时我们会故意增加数据(最终产品的未知大小),因此您可能是故意这样做的。
无论如何,这是一个简短的已发布beginners guide on efficient R代码,您可以阅读(专注于生物学 - 但适用于所有领域)。
希望这有帮助!
注意:刚刚看过zyurnaidi的编辑。这段代码非常相似,如果df2很小,它将与上面的代码一样高效 - 否则重复合并可能会大大降低速度。
答案 1 :(得分:1)
您可以先合并两个数据帧,然后再进行操作:
df.df2 <- merge(df, df2)
df.df2 <- df.df2[with(df.df2, L1 >= L12 & L2 <= L22), ]
df.df2
Name L1 L2 Name2 L12 L22
10 A 61 135 B 52 145
12 A 65 140 B 52 145
13 A 65 150 B 65 150
16 A 65 140 B 65 150
编辑:可能这会适用于你的情况,因为它不需要创建一个大的合并数据帧,它一点一点地工作。但是,该过程本身可能需要比原始解决方案更长的时间。
df.df2 <- data.frame()
for(i in 1:nrow(df)) {
df.df2.i <- merge(df[i, ], df2)
df.df2.i <- df.df2.i[with(df.df2.i, L1 >= L12 & L2 <= L22), ]
df.df2 <- rbind(df.df2, df.df2.i)
}
或使用lapply
df.df2 <- lapply(1:nrow(df), function(i) {
df.df2.i <- merge(df[i, ], df2)
df.df2.i <- df.df2.i[with(df.df2.i, L1 >= L12 & L2 <= L22), ]
})
df.df2 <- do.call(rbind, df.df2)