列中的计数值使用空单元格来指示新数字

时间:2017-05-01 04:07:35

标签: r count aggregate summary

我想使用行为数据来计算捕获的物品数量。这是我的示例数据:

df <- data.frame(id = as.factor(c(51,51,51,51,51,51,51,52,52,52,52,52,52)), 
             type = c("(K)","(K)","(K)","(K)","","","","(K)","(K)","","(K)","","(K)"))

我想根据它们是否连续来计算我的每个“K”。如果是连续的,则字符串应计为1。如果它们之间存在差距,它们都应该算作一个......所以最终的结果将是2.

希望有意义......对于上面的例子,我希望我的最终输出数据看起来像这样

id type tally
1 51  (K)     1
2 52  (K)     3

我认为聚合可能会这样做,但它会计算一列中的总数,因此对于51 tally = 4而不是1

任何帮助将不胜感激

由于 格雷斯

3 个答案:

答案 0 :(得分:4)

在基础R中,您可以使用rle执行此操作。首先按df分割id,然后为每个子组计算"(K)"的序列次数。

sapply(split(df, df$id), function(a)
    length(with(rle(as.character(a$type)), lengths[values == "(K)"])))
#51 52 
# 1  3 

答案 1 :(得分:3)

我们可以使用rleid中的data.table进行尝试。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df)),按&#39; id&#39;分组,找到&#39;类型&#39;的运行长度ID,按&#39; id&#39;分组,&# 39;输入&#39;,获取&#39; val&#39;的length元素的unique这不是空白

library(data.table)
setDT(df)[, val := rleid(type), id][type!="", .(tally = uniqueN(val)), .(id, type)]
#   id type tally
#1: 51  (K)     1
#2: 52  (K)     3

或者我们可以使用tidyverse

library(tidyverse)
df %>%
   mutate(val = cumsum(type != lag(type, default = type[1])))  %>% 
   group_by(id) %>% 
   filter(type!="") %>% 
   summarise(type = first(type), tally= n_distinct(val))
# A tibble: 2 × 3
#      id   type tally
#   <fctr> <fctr> <int>
#1     51    (K)     1
#2     52    (K)     3

答案 2 :(得分:3)

基础R中的rle命令很有用。

temp<- tapply(df$type, df$id, function(x) rle(x == "(K)"))
df.new<- data.frame(id = names(temp), 
                tally = unlist(lapply(temp, function(x) sum(x$values))))