这是对我以前措辞不好的问题的重述。 (对于那些回复它的人,我感谢你们的努力,我很抱歉因为我的问题没有像我应该那样清楚。)我有一个大型数据集,其中一个子集可能如下所示:
a<-c(1,2,3,4,5,1)
b<-c("a","b","a","b","c","a")
c<-c("m","f","f","m","m","f")
d<-1:6
e<-data.frame(a,b,c,d)
如果我想根据特定条件得到第四列中的条目总和,我可以这样做:
attach(e)
total<-sum(e[which(a==3 & b=="a"),4])
detach(e)
但是,我有条件的“向量”(称之为condition_vector),其前四个元素看起来更像是这样:
a==3 & b == "a"
a==2
a==1 & b=="a" & c=="m"
c=="f"
我想创建上面“总计”公式的“通用”版本,通过读入条件的condition_vector来生成总计的results_vector。在此示例中,results_vector中的前四个条目将在概念上按如下方式计算:
results_vector[1]<-sum(e[which(a==3 & b=="a"),4])
results_vector[2]<-sum(e[which(a==2),4])
results_vector[3]<-sum(e[which(a==1 & b=="a" & c=="m"),4])
results_vector[4]<-sum(e[which(c=="f"),4])
我的实际数据集有20多个变量。因此,condition_vector中的每条记录都可以包含1到20个以上的条件(而不是1到3个条件,在本例中使用)。
除了使用解析(eval(text = ...方法(在相对较小的数据集上运行需要很长时间)之外,还有办法实现此目的吗?
提前感谢您提供的任何帮助(我再次道歉,我不像上次那样清楚)。
火花
答案 0 :(得分:2)
这里使用eval(parse(text=..)
使用解决方案,即使显然你发现它很慢:
cond <- c('a==3 & b == "a"','a==2','a==1 & b=="a" & c=="x"','c=="f"')
names(cond) <- cond
results_vector <- lapply(cond,function(x)
sum(dat[eval(parse(text=x)),"d"]))
$`a==3 & b == "a"`
[1] 3
$`a==2`
[1] 2
$`a==1 & b=="a" & c=="m"`
[1] 1
$`c=="f"`
[1] 11
命名条件向量的优点是可以按条件访问结果。
results_vector[cond[2]]
$`a==2`
[1] 2
答案 1 :(得分:0)
这是一个函数,它将每列中的条件作为参数(如果列中没有条件,则NA
作为参数),并在所选data.frame的所选列中求和:
conds.by.col <- function(..., sumcol, DF) #NA if not condition in a column
{
conds.ls <- list(...)
res.ls <- vector("list", length(conds.ls))
for(i in 1: length(conds.ls))
{
res.ls[[i]] <- which(DF[,i] == conds.ls[[i]])
}
res.ls <- res.ls[which(lapply(res.ls, length) != 0)]
which_rows <- Reduce(intersect, res.ls)
return(sum(DF[which_rows , sumcol]))
}
测试:
a <- c(1,2,3,4,5,1)
b <- c("a", "b", "a", "b", "c", "a")
c <- c("m", "f", "f", "m", "m", "f")
d <- 1:6
e <- data.frame(a, b, c, d)
conds.by.col(3, "a", "f", sumcol = 4, DF = e)
#[1] 3
对于多种情况,mapply
:
#all conditions in a data.frame:
myconds <- data.frame(con1 = c(3, "a", "f"),
con2 = c(NA, "a", NA),
con3 = c(1, NA, "f"),
stringsAsFactors = F)
mapply(conds.by.col, myconds[1,], myconds[2,], myconds[3,], MoreArgs = list(sumcol = 4, DF = e))
#con1 con2 con3
# 3 10 6
我认为“效率”不是你说的第一个看这个,但是......