[英]Does dplyr `rowwise()` group in the same way `group_by()` groups?
[英]dplyr grouped cumulative set counting using group_by and rowwise do
我已將數據與組內的排序進行分組,其中每行包含值列表,並且在每個組中,我希望生成每行向每個組中的列表的並集貢獻的新列表值的計數。
這是一個例子:
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
我實際上從這里獲得了大部分解決方案: 累積粘貼(連接)由另一個變量分組的值 (感謝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()
之前單獨創建有序數據框。
非常感謝
蒂姆
你可以用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.