我有一个分组数据框,如下所示:
df <- data.frame(group = rep(1:4, each=3),
lets = rep(LETTERS[1:4], times=3))
对于每一行,我现在想要识别除行本身的lets
之外的同一组中的所有lets
。使用dplyr
我可以获得所有 lets
:
df %>%
group_by(group) %>%
mutate(all_lets_in_group = paste(lets, collapse=','))
但是,如何将当前行的lets
排除在paste()
之外?
答案 0 :(得分:4)
此任务的目的不是很清楚,因此代码清晰度因此受到影响,但仍然存在:
library(tidyverse)
df %>%
group_by(group) %>%
mutate(
all_lets_in_group = lets %>%
map(function(l) setdiff(., l)) %>%
map_chr(function(x) paste(x, collapse=',')))
使用set operation setdiff
从组中减去purrr::map
提供的当前字母,然后使用paste
重新格式化矢量列表并返回为字符向量。< / p>
答案 1 :(得分:2)
不确定dplyr
解决方案,但您可以使用lapply
。
df$all_lets_in_group <- lapply(1:nrow(df), function(x)
paste(with(df, lets[group == group[x] & lets != lets[x]]), collapse = ','))
答案 2 :(得分:1)
使用ave
,sapply
和setdiff
的另一个基础R方法
ave(df$lets, df$group,
FUN=function(i) sapply(i, function(j) paste(setdiff(i, j), collapse=",")))
[1] "B,C" "A,C" "A,B" "A,B" "D,B" "D,A" "D,A" "C,A" "C,D" "C,D" "B,D" "B,C"