如何在应用功能中使用if语句?

时间:2019-04-09 09:16:08

标签: r for-loop if-statement optimization apply

由于我必须读取3个以上的数据,因此我想通过将两个for-loopif-statement更改为apply函数来改善mycode。

下面是我的代码的可复制示例。总体目的(在此示例中)是针对x和y的每个值计算“ c”列中正值和负值的数量。实际上,我有150多个文件可供读取。

# Example of initial data set
df1 <- data.frame(a=rep(c(1:5),times=3),b=rep(c(1:3),each=5),c=rnorm(15))
# Another dataframe to keep track of "c" counts
dfOcc <- data.frame(a=rep(c(1:5),times=3),"positive"=c(0),"negative"=c(0))

到目前为止,我已经完成了这段代码,该代码可以运行,但是速度很慢:

for (i in 1:nrow(df)) {
  x = df[i,"a"]
  y = df[i,"b"]
  if (df[i,"c"]>=0) {
    dfOcc[which(dfOcc$a==x && dfOcc$b==y),"positive"] <- dfOcc[which(dfOcc$a==x && dfOcc$b==y),"positive"] +1
  }else{
    dfOcc[which(dfOcc$a==x && dfOcc$b==y),"negative"] <- dfOcc[which(dfOcc$a==x && dfOcc$b==y),"negative"] +1
  }
}

我不确定代码是由于文件大小(每行26万行)还是由于for-loop而变慢了?

到目前为止,我设法通过以下方式对其进行了改进:

dfOcc[which(dfOcc$a==df$a & dfOcc$b==df$b),"positive"] <- apply(df,1,function(x){ifelse(x["c"]>0,1,0)})

在此示例中,此方法工作正常,但在我的实际情况中无效:

  • 它仅保留正数c的计数,并且两次运行此代码可能会产生反作用。
  • 我的原始数据集是26万行,而我的“跟踪器”是1万行(初始数据集将ab值与其他c值重复

任何关于如何改善这两点的技巧将不胜感激!

2 个答案:

答案 0 :(得分:0)

我认为您可以简单地计算和传播数据。这将更容易,并且适用于任何组和数据集。如果要对group_by(a)group_by(a, b)列进行分组统计,可以将a更改为b

library(dplyr)
library(tidyr)

df1 %>% 
    group_by(a) %>% 
    mutate(sign = ifelse(c > 0, "Positive", "Negative")) %>% 
    count(sign) %>% 
    spread(sign, n)

答案 1 :(得分:0)

打包data.table可能会帮助您一站式完成。

df1 <-  data.table(data.frame(a=rep(c(1:5),times=3),b=rep(c(1:3),each=5),c=rnorm(15)))
posneg <- c("positive" , "negative") # list of columns needed
df1[,(posneg) := list(ifelse(c>0, 1,0), ifelse(c<0, 1,0))] # use list to combine the 2 ifelse conditions


有关更多信息,请尝试

?data.table

如果您真的希望正负计数位于单独的数据框中,

dfOcc <- df1[,c("a", "positive","negative")]