从+/-组合的输入数据帧中提取更高级别的组合,但仅允许在输入中找到的组合

问题描述 投票:0回答:1

我需要重新打开这个问题,因为我面临着一个非常类似的问题,接受的答案不再有效,而且我不知道如何针对这种特殊情况修改它。

我有一个 +/- 组合的输入数据框,用于 n 标记(按列),例如:

in_df <- data.frame(M1=c('-','+','+','-'), M2=c('-','-','+','-'), M3=c('+','-','-','-'))

看起来像:

>   in_df
  M1 M2 M3
1  -  -  +
2  +  -  -
3  +  +  -
4  -  -  -

我需要提取更高级别的组合(在本例中为 1 和 2 个标记组,总共有 3 个)。

为此,我使用上一个问题中接受的答案:

  nullgrid_expand_dt <- function(df, ...){
    as.data.frame(do.call(data.table::CJ, args = c(as.list(df[c(NA, seq_len(nrow(df))), ]),
                          sorted = FALSE,
                          unique = TRUE)))
  }
  #
  out_df <- nullgrid_expand_dt(in_df)

产生输出数据帧:

>   out_df
     M1   M2   M3
1  <NA> <NA> <NA>
2  <NA> <NA>    +
3  <NA> <NA>    -
4  <NA>    - <NA>
5  <NA>    -    +
6  <NA>    -    -
7  <NA>    + <NA>
8  <NA>    +    +
9  <NA>    +    -
10    - <NA> <NA>
11    - <NA>    +
12    - <NA>    -
13    -    - <NA>
14    -    -    +
15    -    -    -
16    -    + <NA>
17    -    +    +
18    -    +    -
19    + <NA> <NA>
20    + <NA>    +
21    + <NA>    -
22    +    - <NA>
23    +    -    +
24    +    -    -
25    +    + <NA>
26    +    +    +
27    +    +    -

当我最初提出问题时,这非常有效,因为我的输入数据框具有我的 5 个标记的所有可能的“最后一级”组合。

输入数据框现在不包含 3 个标记的所有可能组合。请注意,例如

+/+/+
-/+/+
不存在,因此输出数据框中不应允许它们。同样,不应该允许
NA/+/+
-/+/NA
等。

这正是@ekoam 在回答上一个问题时提出的担忧,但当时这并不重要。

下面,我将

out_df
粘贴到不应该存在的行上,并用
X
标记。如果能够在
nullgrid_expand_dt
函数中以有效的方式解释这一点,那就太好了。

>   out_df
     M1   M2   M3
1  <NA> <NA> <NA>   X
2  <NA> <NA>    +
3  <NA> <NA>    -
4  <NA>    - <NA>
5  <NA>    -    +
6  <NA>    -    -
7  <NA>    + <NA>
8  <NA>    +    +   X
9  <NA>    +    -
10    - <NA> <NA>
11    - <NA>    +
12    - <NA>    -
13    -    - <NA>
14    -    -    +
15    -    -    -
16    -    + <NA>   X
17    -    +    +   X
18    -    +    -   X
19    + <NA> <NA>
20    + <NA>    +   X
21    + <NA>    -
22    +    - <NA>
23    +    -    +   X
24    +    -    -
25    +    + <NA>
26    +    +    +   X
27    +    +    -
r dataframe function data.table combinations
1个回答
0
投票
nullgrid_expand_dt <- function(df) {
  tmp <- c(TRUE, FALSE)
  tmp <- as.matrix(CJ(tmp, tmp, tmp, unique=TRUE)[-.N])
  OUT <- lapply(
    seq_len(nrow(in_df)),
    \(i) {
      x <- in_df[rep(i, 7), ]
      x[tmp] <- NA_character_
      x
    }
  ) |> rbindlist() |> unique()
  setorderv(OUT, names(OUT))
  OUT
}

nullgrid_expand_dt(in_df)
#         M1     M2     M3
#     <char> <char> <char>
#  1:   <NA>   <NA>      +
#  2:   <NA>   <NA>      -
#  3:   <NA>      +   <NA>
#  4:   <NA>      +      -
#  5:   <NA>      -   <NA>
#  6:   <NA>      -      +
#  7:   <NA>      -      -
#  8:      +   <NA>   <NA>
#  9:      +   <NA>      -
# 10:      +      +   <NA>
# 11:      +      +      -
# 12:      +      -   <NA>
# 13:      +      -      -
# 14:      -   <NA>   <NA>
# 15:      -   <NA>      +
# 16:      -   <NA>      -
# 17:      -      -   <NA>
# 18:      -      -      +
# 19:      -      -      -
© www.soinside.com 2019 - 2024. All rights reserved.