关于查找组合匹配的一般问题

General Question about Finding Combination Matches

我对用 R 编写代码还很陌生(如有任何术语、礼仪等方面的错误,请多多包涵)。我决定开始一个项目,这样我可以获得更多的经验。我是一名研究动物骨骼的考古学家,在我的领域中,我们有一个称为最小元素数 (MNE) 的定量单位。这个单位很难手动计算,我正在尝试自动计算。 MNE 是可以代表碎片骨骼集合的完整骨骼的最小数量。所以,我有代表骨骼某些部分的骨骼零件代码,并且我已经制定了用于查找特定序列中的组合的规则。某些组合等于 1 个 MNE,等等

这是我的数据框示例:

EL_S    PT
1P_L    1
HU_L    107,107,107,108,108
FE_L    103,105,108,110,103,103,108,110,105,107,103

EL_S 表示骨骼元素和侧面(因此 FE_L 等于左股骨),列 PT 是与该骨骼关联的零件代码的字符向量和侧面。例如,103 和 105 的组合等于 1 MNE。更具体地说,最好的方法是:

  1. 为 PT 组合分配某些值(但是,PT 1 等于一整根骨头,是 1 个 MNE。因此,即使它不是组合,我也必须给它一个值。 )

  2. 从字符向量中查找并提取这些组合(或单个值)

  3. 计算它们的出现次数

  4. 将该计数加载到新的 "MNE" 列

  5. 并按指定顺序执行所有操作

我当然知道这是来自这个社区的疯狂的具体问题。我完全不期望有人会为我解决所有这些问题。但是,如果有人对这个过程中的任何步骤使用特定功能等有任何建议,我将不胜感激。我正在考虑使用 stringr 将代码字符串组合成 103105,然后计算这些匹配项。但我不太确定这是最有效的方法。再次感谢您的帮助!

编辑澄清:

在一个完美的世界里,这就是我希望创造的。

我从上面的例子开始:

EL_S    PT
1P_L    1
HU_L    107,107,107,108,108
FE_L    103,105,108,110,103,103,108,110,105,107,103

我想先找到并提取 PT 1。该零件代码等于 1 MNE。

EL_S    PT                                          MNE
1P_L                                                1
HU_L    107,107,107,108,108
FE_L    103,105,108,110,103,103,108,110,105,107,103

接下来我要查找并提取组合 103,105。这等于 1 个跨国公司。在上面的 table 中,FE_L 有两个 103,105 组合的实例,因此 MNE = 2.

EL_S    PT                            MNE
1P_L                                  1
HU_L    107,107,107,108,108
FE_L    108,110,103,103,108,110,107   2

这将一直持续下去,直到没有更多的零件代码。在找到特定组合(或单个 PT 值)时添加到 MNE 列。我希望这是有道理的。如果这里有任何不清楚的地方,我们深表歉意。

假设 df 看起来像这样:

df <- read.table(text = "EL_S    PT
1P_L    1
HU_L    107,107,107,108,108
FE_L    103,105,108,110,103,103,108,110,105,107,103", header = TRUE)


  EL_S                                          PT
1 1P_L                                           1
2 HU_L                         107,107,107,108,108
3 FE_L 103,105,108,110,103,103,108,110,105,107,103

我们可以将其转换为宽格式,然后添加您要统计的列,该列最初用零填充:

library(tidyverse)

df_wide <- df %>% 
  separate_rows("PT") %>% 
  count(EL_S, PT) %>% 
  spread(PT, n, fill = 0) %>% 
  mutate(MNE = 0)


# A tibble: 3 x 8
  EL_S    `1` `103` `105` `107` `108` `110`   MNE
  <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1P_L      1     0     0     0     0     0     0
2 FE_L      0     4     2     1     2     2     0
3 HU_L      0     0     0     3     2     0     0

我认为我们需要迭代进行(因为我们做事的顺序很重要)。
您示例中的第一步是零件代码 1。我们 select 正确的计数列,应用最小值,将其添加到计数列中,然后从我们已说明的观察结果中减去它。

part_codes <- c("1")
num_mne <- apply(df_wide[part_codes], 1, FUN=min)
df_wide$MNE <- df_wide$MNE + num_mne
df_wide[part_codes] <- df_wide[part_codes] - num_mne


# A tibble: 3 x 8
  EL_S    `1` `103` `105` `107` `108` `110`   MNE
  <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1P_L      0     0     0     0     0     0     1
2 FE_L      0     4     2     1     2     2     0
3 HU_L      0     0     0     3     2     0     0

然后,我们可以对103,105做同样的事情:

part_codes <- c("103", "105")
num_mne <- apply(df_wide[part_codes], 1, FUN=min)
df_wide$MNE <- df_wide$MNE + num_mne
df_wide[part_codes] <- df_wide[part_codes] - num_mne


# A tibble: 3 x 8
  EL_S    `1` `103` `105` `107` `108` `110`   MNE
  <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1P_L      0     0     0     0     0     0     1
2 FE_L      0     2     0     1     2     2     2
3 HU_L      0     0     0     3     2     0     0

由于除了 part_codes 变量之外代码是相同的,我认为您可以将其包装在一个函数中并循环(或应用)您要处理的零件代码组合。

这是你想要的吗?