我将数据与组内的排序进行分组,其中每行包含值列表,并且在每个组中,我希望生成每行向每个组中的列表的并集贡献的新列表值的计数。
以下是一个例子:
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
我想要的输出(按每个组内下降顺序排序后)将如下:
# id order content cc
# 1 a 7 A, B, C 3
# 2 a 5 A, B 3
# 3 a 3 D, E 5
# 4 b 9 A, B 2
# 5 b 4 A, B, C 3
# 6 b 1 A, B 3
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
我实际上从这里获得了大部分解决方案:Cumulatively paste (concatenate) values grouped by another variable(感谢akrun)。生成的值似乎是正确的,但它们与源数据框中的正确行无关:
res
# id order content n n1 vars
# 1 a 7 A, B, C 1 1 2
# 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 2
# 6 b 1 A, B 6 4 3
正如您所看到的(查看相当于上述cc的vars列)组'a'值2和3相反,对于组'b',第二个2和3值相反。
实际上我找出了上面的错误,testdf $内容(显然)没有与dplyr'd数据框相同。最初我有.$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
这就产生了我的期望:
# 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
所以现在我的问题是有更好的方法来引用do()
中的整个dplyr修改数据框(以便正确排序content
) - 我认为.
只是当前行不是吗?能够这样做可以避免我必须在do()
之前单独创建有序数据框。
非常感谢
添
答案 0 :(得分:1)
您可以使用Reduce
模式和accumulate
模式创建累积不同的元素,然后使用lengths
函数返回累积的不同计数,这样可以避免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