我需要重新打开这个问题,因为我面临着一个非常类似的问题,接受的答案不再有效,而且我不知道如何针对这种特殊情况修改它。
我有一个 +/- 组合的输入数据框,用于 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 + + -
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: - - -