R语言 如何过滤掉顺序不重要的组合?[duplicate]

bybem2ql  于 2023-03-15  发布在  其他
关注(0)|答案(4)|浏览(150)

此问题在此处已有答案

R - Expand Grid Without Duplicates(2个答案)
Non-redundant version of expand.grid(10个答案)
4天前关闭。
我有一堆1、2和3的组合:

> tidyr::crossing(X1 = c(1,2,3), X2 = c(1,2,3))
# A tibble: 9 × 2
     X1    X2
  <dbl> <dbl>
1     1     1
2     1     2
3     1     3
4     2     1
5     2     2
6     2     3
7     3     1
8     3     2
9     3     3

在这个例子中,我想过滤掉第4、6、7和8行,因为顺序并不重要,也就是说,(1,2)和(2,1)是一样的。
有没有办法生成这样的组合,或者在已经生成 Dataframe 的情况下过滤掉行?

rseugnpd

rseugnpd1#

您可以filter行,其中X1小于或等于X2:

library(dplyr)
library(tidyr)
crossing(X1 = c(1,2,3), X2 = c(1,2,3)) %>% 
  filter(X1 <= X2)

#      X1    X2
# 1     1     1
# 2     1     2
# 3     1     3
# 4     2     2
# 5     2     3
# 6     3     3

要获得更通用的解决方案,请使用repeats = TRUE检查gtools::combinations

gtools::combinations(3, 3, c(1, 2, 3), repeats = TRUE)

#       [,1] [,2] [,3]
#  [1,]    1    1    1
#  [2,]    1    1    2
#  [3,]    1    1    3
#  [4,]    1    2    2
#  [5,]    1    2    3
#  [6,]    1    3    3
#  [7,]    2    2    2
#  [8,]    2    2    3
#  [9,]    2    3    3
# [10,]    3    3    3

或者使用is.unsortedrowwise

crossing(X1 = c(1,2,3), X2 = c(1,2,3), X3 = c(1,2,3)) %>% 
  rowwise() %>% 
  filter(!is.unsorted(across(X1:X3)))

以R为基简化:

df <- expand.grid(X1 = c(1,2,3), X2 = c(1,2,3), X3 = c(1,2,3))
df[!apply(df, 1, is.unsorted), ]
vngu2lb8

vngu2lb82#

我们可以将两列的minmax值组合在一起,然后slice输出一个条目。
这对数字列和字符列都有效。

library(dplyr)

df %>% 
  mutate(tmp = paste0(pmin(X1, X2), pmax(X1, X2))) %>% 
  slice_head(n = 1, by = tmp) %>% 
  select(-tmp)

# A tibble: 6 × 2
     X1    X2
  <dbl> <dbl>
1     1     1
2     1     2
3     1     3
4     2     2
5     2     3
6     3     3
wd2eg0qa

wd2eg0qa3#

可以重复两次向量并使用combn

unique(t(combn(rep(1:3, each = 2), 2)))

#      [,1] [,2]
# [1,]    1    1
# [2,]    1    2
# [3,]    1    3
# [4,]    2    2
# [5,]    2    3
# [6,]    3    3

注意,传入combn的重复向量必须是递增的,也就是说,必须设置each = 2而不是times = 2;否则,

unique(t(combn(rep(1:3, times = 2), 2)))

#      [,1] [,2]
# [1,]    1    2
# [2,]    1    3
# [3,]    1    1
# [4,]    2    3
# [5,]    2    1
# [6,]    2    2
# [7,]    3    1
# [8,]    3    2
# [9,]    3    3
svmlkihl

svmlkihl4#

我希望这一招适用于你的情况

x <- 1:3
data.frame(
  X1 = rep(x, rev(seq_along(x))),
  X2 = sequence(rev(seq_along(x)), x)
)

它给出了

X1 X2
1  1  1
2  1  2
3  1  3
4  2  2
5  2  3
6  3  3

相关问题