当结果是字符串而不是相同的顺序时,删除重复的结果

时间:2017-10-02 17:50:28

标签: r

我想创建一个数据框,其中包含滚动两个骰子的可能结果。其重点是单独运行模拟并使用结果数填充数据框。我编写了以下代码来创建数据框:

dice1 <- sort(rep(1:6,6))
dice2 <- rep(1:6,6)
dicesum <- dice1 + dice2

df <- data.frame(dice1, dice2, dicesum)

> str(df)
'data.frame':   36 obs. of  3 variables:
 $ dice1  : int  1 1 1 1 1 1 2 2 2 2 ...
 $ dice2  : int  1 2 3 4 5 6 1 2 3 4 ...
 $ dicesum: int  2 3 4 5 6 7 3 4 5 6 ...

> head(df)
  dice1 dice2 dicesum
1     1     1       2
2     1     2       3
3     1     3       4
4     1     4       5
5     1     5       6
6     1     6       7

我首先考虑创建对,例如(1,6),...,(6,6),以便在(dice1,dice2)==(dice2,dice1)时删除重复项。然而,结果是不可取的,因为两个实例都被移除(例如(1,6)和(6,1))并且也移除了双重(例如(2,2),(6,6))。

注意:我认为(1,6)和(6,1)重复结果。 问题:从数据框中删除重复结果的最佳方法是什么?

5 个答案:

答案 0 :(得分:1)

使用编辑问题后的数据结构,我相信以下内容可以做到。

inx <- duplicated(t(apply(df, 1, sort)))
df[!inx, ]

上面代码的单行显而易见。

答案 1 :(得分:1)

如果你自己为模拟生成数据帧,另一种没有重复的方法是避免生成它们。

例如,您可以使用combinations包中的gtools函数生成所需的数据框:

df <- as.data.frame(gtools::combinations(6, 2, repeats.allowed=TRUE))
names(df) <- c("dice1", "dice2")
df$dicesum <- df$dice1 + df$dice2
df
#>    dice1 dice2 dicesum
#> 1      1     1       2
#> 2      1     2       3
#> 3      1     3       4
#> 4      1     4       5
#> 5      1     5       6
#> 6      1     6       7
#> 7      2     2       4
#> 8      2     3       5
#> 9      2     4       6
#> 10     2     5       7
#> 11     2     6       8
#> 12     3     3       6
#> 13     3     4       7
#> 14     3     5       8
#> 15     3     6       9
#> 16     4     4       8
#> 17     4     5       9
#> 18     4     6      10
#> 19     5     5      10
#> 20     5     6      11
#> 21     6     6      12

答案 2 :(得分:1)

使用in the answer of markdly的方法(&#34; 另一种没有重复的方法是避免生成它们&#34;)可以实现为非-equi self join 使用data.table

library(data.table)
(DT<- data.table(1:6))[DT, on = .(V1 >= V1), .(dice1 = i.V1, dice2 = x.V1)][
  , dicesum := dice1 + dice2][]
    dice1 dice2 dicesum
 1:     1     1       2
 2:     1     2       3
 3:     1     3       4
 4:     1     4       5
 5:     1     5       6
 6:     1     6       7
 7:     2     2       4
 8:     2     3       5
 9:     2     4       6
10:     2     5       7
11:     2     6       8
12:     3     3       6
13:     3     4       7
14:     3     5       8
15:     3     6       9
16:     4     4       8
17:     4     5       9
18:     4     6      10
19:     5     5      10
20:     5     6      11
21:     6     6      12
    dice1 dice2 dicesum

答案 3 :(得分:0)

df <- data_frame(pairs = list(c(1,2), c(2,1), c(2,2)))

df_sum是您的输入数据框:

  

df_sum&lt; - df%&gt;%rowwise()%&gt;%mutate(sum = sum(pairs))%&gt;%ungroup()

> df_sum %>% glimpse()
Observations: 3
Variables: 2
$ pairs <list> [<1, 2>, <2, 1>, <2, 2>]
$ sum   <dbl> 3, 3, 4

删除pairs列表列中的重复项:

  

res&lt; - df_sum%&gt;%rowwise()%&gt; $%mutate(pairs = list(sort(pairs)))%&gt;%unique()

res %>% glimpse()
Observations: 2
Variables: 2
$ pairs <list> [<1, 2>, <2, 2>]
$ sum   <dbl> 3, 4

答案 4 :(得分:0)

这是基础R的解决方案(记住原始问题)

数据:

structure(list(pairs = c("(1,1)", "(1,2)", "(1,3)", "(1,4)", 
"(1,5)", "(1,6)", "(2,1)", "(2,2)", "(2,3)", "(2,4)", "(2,5)", 
"(2,6)", "(3,1)", "(3,2)", "(3,3)", "(3,4)", "(3,5)", "(3,6)", 
"(4,1)", "(4,2)", "(4,3)", "(4,4)", "(4,5)", "(4,6)", "(5,1)", 
"(5,2)", "(5,3)", "(5,4)", "(5,5)", "(5,6)", "(6,1)", "(6,2)", 
"(6,3)", "(6,4)", "(6,5)", "(6,6)"), sum = c(2L, 3L, 4L, 5L, 
6L, 7L, 3L, 4L, 5L, 6L, 7L, 8L, 4L, 5L, 6L, 7L, 8L, 9L, 5L, 6L, 
7L, 8L, 9L, 10L, 6L, 7L, 8L, 9L, 10L, 11L, 7L, 8L, 9L, 10L, 11L, 
12L)), .Names = c("pairs", "sum"), row.names = c("1", "2", "3", 
"4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", 
"16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", 
"27", "28", "29", "30", "31", "32", "33", "34", "35", "36"), class = "data.frame")

数据框的名称为dups

删除括号和逗号,将字符串拆分为字符,转换为数字并排序

b = lapply(strsplit(gsub("\\((\\d),(\\d)\\)", "\\1\\2", dups$pairs), ""), function(x) sort(as.numeric(x)))

折叠到角色向量

b = lapply(b, function(x) paste(x, collapse = ""))

重复的条目

b = duplicated(unlist(b))

显示除重复元素之外的所有元素

dups[!b,]
#output:  
  pairs sum
1  (1,1)   2
2  (1,2)   3
3  (1,3)   4
4  (1,4)   5
5  (1,5)   6
6  (1,6)   7
8  (2,2)   4
9  (2,3)   5
10 (2,4)   6
11 (2,5)   7
12 (2,6)   8
15 (3,3)   6
16 (3,4)   7
17 (3,5)   8
18 (3,6)   9
22 (4,4)   8
23 (4,5)   9
24 (4,6)  10
29 (5,5)  10
30 (5,6)  11
36 (6,6)  12