关于查找组合匹配的一般问题
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。更具体地说,最好的方法是:
为 PT 组合分配某些值(但是,PT 1 等于一整根骨头,是 1 个 MNE。因此,即使它不是组合,我也必须给它一个值。 )
从字符向量中查找并提取这些组合(或单个值)
计算它们的出现次数
将该计数加载到新的 "MNE" 列
并按指定顺序执行所有操作
我当然知道这是来自这个社区的疯狂的具体问题。我完全不期望有人会为我解决所有这些问题。但是,如果有人对这个过程中的任何步骤使用特定功能等有任何建议,我将不胜感激。我正在考虑使用 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
变量之外代码是相同的,我认为您可以将其包装在一个函数中并循环(或应用)您要处理的零件代码组合。
这是你想要的吗?
我对用 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。更具体地说,最好的方法是:
为 PT 组合分配某些值(但是,PT 1 等于一整根骨头,是 1 个 MNE。因此,即使它不是组合,我也必须给它一个值。 )
从字符向量中查找并提取这些组合(或单个值)
计算它们的出现次数
将该计数加载到新的 "MNE" 列
并按指定顺序执行所有操作
我当然知道这是来自这个社区的疯狂的具体问题。我完全不期望有人会为我解决所有这些问题。但是,如果有人对这个过程中的任何步骤使用特定功能等有任何建议,我将不胜感激。我正在考虑使用 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
变量之外代码是相同的,我认为您可以将其包装在一个函数中并循环(或应用)您要处理的零件代码组合。
这是你想要的吗?