dplyr使用group_by和rowwise do对累积集合计数进行分组
我对数据进行了分组,分组中的每一行都包含一个值列表,在每个组中,我希望生成一个新的列表值计数,这些值由每一行贡献给每个组中列表的并集 以下是一个例子:dplyr使用group_by和rowwise do对累积集合计数进行分组,r,dplyr,R,Dplyr,我对数据进行了分组,分组中的每一行都包含一个值列表,在每个组中,我希望生成一个新的列表值计数,这些值由每一行贡献给每个组中列表的并集 以下是一个例子: require(dplyr) content <- list(c("A", "B"), c("A", "B", "C"), c("D", "E"), c("A", "B"), c("A", "B"), c("A", "B", "C")) id <- c("a", "a", "a", "b", "b", "b") order <-
require(dplyr)
content <- list(c("A", "B"), c("A", "B", "C"), c("D", "E"), c("A", "B"), c("A", "B"), c("A", "B", "C"))
id <- c("a", "a", "a", "b", "b", "b")
order <- c(5, 7, 3, 1, 9, 4)
testdf <- data.frame(id, order, cbind(content))
testdf
# id order content
# 1 a 5 A, B
# 2 a 7 A, B, C
# 3 a 3 D, E
# 4 b 1 A, B
# 5 b 9 A, B
# 6 b 4 A, B, C
cn(累积新)确实比cc(累积计数)更可取,但上面的映射到我下面的尝试,cn随后很容易计算。以下是我尝试的解决方案,但不起作用:
res <- testdf %>%
arrange(id, desc(order)) %>%
mutate(n=row_number()) %>%
group_by(id) %>%
mutate(n1=first(n)) %>%
rowwise() %>%
bind_cols(do(.,data.frame(vars=length(unique(unlist(testdf$content[.$n1:.$n])))))) %>%
data.frame
如您所见(查看与上述cc等效的vars列),组“a”的值2和3颠倒,组“b”的第二个值2和3颠倒
事实上,我已经解决了上面的问题,,testdf$内容(显然)与dplyr的数据帧顺序不同。最初我使用的是$content
而不是testdf$content
,这产生了更奇怪的输出。所以我试着分两个阶段来做:
res <- testdf %>%
arrange(id, desc(order)) %>%
mutate(n=row_number()) %>%
group_by(id) %>%
mutate(n1=first(n))
res <- res %>%
rowwise() %>%
bind_cols(do(.,data.frame(vars=length(unique(unlist(res$content[.$n1:.$n])))))) %>%
data.frame
所以我现在的问题是,有没有更好的方法来引用do()
(以便content
的顺序正确)中整个dplyr修改的数据帧?我认为
只是当前行,不是吗?这样做可以避免我必须在do()
之前单独创建有序数据框
非常感谢
Tim您可以使用
Reduce
函数和累积
模式创建累积不同元素,然后使用length
函数返回累积不同计数,这避免了rowwise()
操作:
library(dplyr)
testdf %>%
arrange(desc(order)) %>%
group_by(id) %>%
mutate(cc = lengths(Reduce(function(x, y) unique(c(x, y)), content, acc = T))) %>%
arrange(id)
#Source: local data frame [6 x 4]
#Groups: id [2]
# id order content cc
# <fctr> <dbl> <list> <int>
#1 a 7 <chr [3]> 3
#2 a 5 <chr [2]> 3
#3 a 3 <chr [2]> 5
#4 b 9 <chr [2]> 2
#5 b 4 <chr [3]> 3
#6 b 1 <chr [2]> 3
库(dplyr)
testdf%>%
排列(描述(订单))%>%
分组依据(id)%>%
变异(cc=长度(减少(函数(x,y)唯一(c(x,y)),内容,acc=T))%>%
安排(id)
#来源:本地数据帧[6 x 4]
#组别:id[2]
#id订单内容cc
#
#1 a 7 3
#2 a 5 3
#3 a 3 5
#4 b 9 2
#5 b 4 3
#6b13
我对所有步骤都有点困惑,但是假设您已经对数据进行了适当的排序和分组,您可以使用cumsum(!duplicated(unlist(x))[cumsum(length(x))]
进行累积计数,其中x
是有序的“内容”——例如列表(c(“a”、“B”、“c”)、c(“a”、“B”)、c(“D”、“e”)
“a”组中的“内容”和列表(c(“a”、“B”)、c(“a”、“B”、“c”)、c(“a”、“B”))
在“B”组中。谢谢你的回复-我很快就找到了,但我不确定该在哪里尝试,它是否应该取代整个行方式()
和绑定列方式()
?我天真地尝试了res%>%cumsum(!duplicated(unlist(content)))[cumsum(长度)](内容))]
哪一个给了NA?在你的代码之后,我有了一些类似于testdf%%>%arrange(id,desc(order))%%>%groupby(id)%%>%mutate(cumsum(!duplicated(unlist(content)))[cumsum(length(content))
的东西,在mindOk谢谢-这对我来说很有用,尽管我不太确定如何使用cumsum(length(content))从列表中进行选择)行得通。我认为@Psidom的解决方案可能更容易理解,因此我将接受它作为解决方案。再次感谢您的贡献。顺便说一下,我喜欢您使用带有“累积”的方法"为此目的命名,尽管双重使用有点混乱。谢谢,这是一个很好的解决方案!对于何时需要行操作与何时能够使用向量化解决方案,是否有经验法则?我不确定是否有经验法则,但为了避免在可以向量化时使用行操作,这将是我的经验法则,因为行操作是通常很贵。我可以问一下上面第一次排列和第二次排列的顺序是否重要。有人可能会认为第二次排列将在第三次排列中排列,但我不确定这是否如预期的那样有效?谢谢。就我所知,groupby
和arrange
的顺序应该不会影响到我。我找不到强有力的支持但是你可能会发现这是有用的:啊,是的,很有趣,所以它过去是有区别的,但现在不是0.5.0之后,也许我看到了一些关于这个的老帖子。谢谢。
res <- testdf %>%
arrange(id, desc(order)) %>%
mutate(n=row_number()) %>%
group_by(id) %>%
mutate(n1=first(n))
res <- res %>%
rowwise() %>%
bind_cols(do(.,data.frame(vars=length(unique(unlist(res$content[.$n1:.$n])))))) %>%
data.frame
# id order content n n1 vars
# 1 a 7 A, B, C 1 1 3
# 2 a 5 A, B 2 1 3
# 3 a 3 D, E 3 1 5
# 4 b 9 A, B 4 4 2
# 5 b 4 A, B, C 5 4 3
# 6 b 1 A, B 6 4 3
library(dplyr)
testdf %>%
arrange(desc(order)) %>%
group_by(id) %>%
mutate(cc = lengths(Reduce(function(x, y) unique(c(x, y)), content, acc = T))) %>%
arrange(id)
#Source: local data frame [6 x 4]
#Groups: id [2]
# id order content cc
# <fctr> <dbl> <list> <int>
#1 a 7 <chr [3]> 3
#2 a 5 <chr [2]> 3
#3 a 3 <chr [2]> 5
#4 b 9 <chr [2]> 2
#5 b 4 <chr [3]> 3
#6 b 1 <chr [2]> 3