由于我必须读取3个以上的数据,因此我想通过将两个for-loop
和if-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
的计数,并且两次运行此代码可能会产生反作用。a
和b
值与其他c
值重复任何关于如何改善这两点的技巧将不胜感激!
答案 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")]