我有几个实验的数据框。我希望计算每次连续实验后获得的独特值的累积数量。
例如,考虑:
exp cum_unique_entries
1 exp1 4
2 exp2 6
3 exp3 7
4 exp4 9
唯一条目总数为九。现在我希望结果如下:
from pyomo.opt import SolverFactory
opt = SolverFactory('ipopt')
result = opt.solve(model)
最后,我想以条形图的形式绘制它。 我可以用for循环方法做到这一点,但感觉必须有更优雅的方式。
答案 0 :(得分:6)
这是dplyr
的另一个解决方案:
library(dplyr)
test %>%
mutate(cum_unique_entries = cumsum(!duplicated(entries))) %>%
group_by(exp) %>%
slice(n()) %>%
select(-entries)
或
test %>%
mutate(cum_unique_entries = cumsum(!duplicated(entries))) %>%
group_by(exp) %>%
summarise(cum_unique_entries = last(cum_unique_entries))
<强>结果:强>
# A tibble: 4 x 2
exp cum_unique_entries
<fctr> <int>
1 exp1 4
2 exp2 6
3 exp3 7
4 exp4 9
注意:强>
首先查找所有非重复项(cumsum(!duplicated(entries))
),group_by
exp
的累积总和,然后取每个组的最后cumsum
,这个数字将是每个组的累积唯一条目。
答案 1 :(得分:3)
使用library(data.table)
,我们可以
setDT(test)[, new := cumsum(!duplicated(entries))]
test[, .(cum_unique_entries = new[.N]), by = exp]
答案 2 :(得分:1)
1)sqldf 这可以在一个复杂的连接中完成:
library(sqldf)
sqldf("select b.exp, count(Distinct a.entries) cum
from test a join test b on a.exp <= b.exp group by b.exp")
,并提供:
exp cum
1 exp1 4
2 exp2 6
3 exp3 7
4 exp4 9
这个想法可以使用其他框架转换为相应的代码,尽管它在base和dplyr中效率相当低,因为必须进行nxn笛卡尔连接然后对其进行子集,而SQL可能会优化它以避免生成大的中间结果。
2)rollapplyr 按test
排序exp
并使用rollapplyr
计算唯一条目的累计数量。然后使用!duplicated(..., fromLast = TRUE)
获取每个exp
组的最后一个
library(zoo)
n <- nrow(test)
test_sorted <- test[order(test$exp), ]
len_uniq <- function(x) length(unique(x))
test_cum <- transform(test_sorted, cum = rollapplyr(entries, 1:n, len_uniq, fill = NA))
test_cum[!duplicated(test_cum$exp, fromLast = TRUE), -2]
,并提供:
exp cum
4 exp1 4
8 exp2 6
12 exp3 7
17 exp4 9
答案 3 :(得分:0)
我会使用reshape包中的cast函数(simple example,full reference)。 它应该像
一样简单reshape::cast(test, exp~., value="entries", function(x) length(unique(x)) )
我正在做的是告诉函数考虑你的数据集,使用test
变量作为id-variable并“忽略”所有其他变量(即.
含义),添加在名为function(x) length(unique(x))
的列上计算的给定函数(entries
)返回的“指标”。
它类似于SQL
聚合函数和group by
构造!
它的SQL等价是
SELECT exp, count(distinct entries)
FROM test
GROUP BY test
答案 4 :(得分:0)
temp = split(test$entries, test$exp)
data.frame(E = names(temp),
V = sapply(Reduce(c, temp, accumulate = TRUE), function(x) length(unique(x))))
# E V
#1 exp1 4
#2 exp2 6
#3 exp3 7
#4 exp4 9