R 基于查找表(具有多个列)在数据框中查找(和替换)值
更新如下 :原件 我试图找到一种最优雅、最简单、最简洁的方法来替换某些列的值,这种方法基于匹配另一个数据帧中的两列 下面是一个表,其中包含我希望根据其包含的值替换的列R 基于查找表(具有多个列)在数据框中查找(和替换)值,r,R,更新如下 :原件 我试图找到一种最优雅、最简单、最简洁的方法来替换某些列的值,这种方法基于匹配另一个数据帧中的两列 下面是一个表,其中包含我希望根据其包含的值替换的列 > cost.table Identifier Phase.0.Difficulty Phase.1.Complexity Phase.2.Complexity Phase.3.Complexity Phase.4.Complexity Phase.5.Complexity 1 FS1
> cost.table
Identifier Phase.0.Difficulty Phase.1.Complexity Phase.2.Complexity Phase.3.Complexity Phase.4.Complexity Phase.5.Complexity
1 FS1 Low Low Low Medium Medium High
2 FS2 High High High Medium Medium Medium
3 FS3 High Low Low High High High
4 FS4 High Medium Medium Medium Medium Medium
5 FS5 High Medium Medium High Medium Medium
Phase.6.Complexity Transaction.Feasibility Approach
1 High Medium B
2 Medium Medium I
3 High Medium B
4 Medium Medium I
5 Medium Medium B
下面是我希望用来找到正确替换值的查找表
> cost.approach.difficulty
Approach Difficulty Phase 0 Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 Phase 6
1 B High 18102.778 29481.67 29481.67 11822.222 30737.78 21634.67 12768.00
2 B Low 3860.694 15978.47 11175.69 7448.000 12768.00 11467.56 11467.56
3 B Medium 5323.694 24974.44 15184.17 9221.333 15368.89 12768.00 12768.00
4 I High 18102.778 74184.44 29481.67 44747.111 69160.00 45249.56 32245.11
5 I Low 3860.694 26008.89 11175.69 16551.111 35910.00 16876.22 14275.33
6 I Medium 5323.694 41156.11 15184.17 22373.556 44776.67 23378.44 16876.22
7 RV High 18102.778 28373.33 29481.67 44747.111 69160.00 45249.56 32245.11
8 RV Low 3860.694 14870.14 11175.69 16551.111 44776.67 16876.22 14275.33
9 RV Medium 5323.694 22757.78 15184.17 22373.556 44776.67 23378.44 16876.22
我正试图找到一个简单的解决方案,在cost.approach.demobility表中查找“approach”和“demobility”对应的值
因此,例如,在cost.table中,我希望将第一行、第0.0.combiness列替换为3860.694,因为这是一种“B”方法,难度较低
是否有人有一个优雅、简单的解决方案,可以基于两列或多列查找值并沿多列替换值
谢谢,
安德鲁
更新-
有两个建议的答案与使用合并相关。我的目标是找到一个更简洁、简洁、优雅的解决方案。以下是我迄今为止提出的最好的建议:
cost.approach.difficulty$Phase.0[match(paste(cost.table$Approach, cost.table$Phase.0.Difficulty), paste(cost.approach.difficulty$Approach, cost.approach.difficulty$Difficulty))]
这个解决方案的问题是,我需要提前知道列名,但仍然像黑客一样。有人有更简洁的解决方案吗?在这种情况下,merge应该做到以下几点:
cost.table <- merge(
x = cost.table,
y = cost.approach.difficulty[c("Approach", "Difficulty", "Phase.0")],
by.x = c("Phase.0.Difficulty", "Approach"),
by.y = c("Difficulty", "Approach"), sort = FALSE
)
cost.table$Phase.0.Difficulty <- NULL
names(cost.table)[names(cost.table) == "Phase.0"] <- "Phase.0.Difficulty"
cost.table
Approach Identifier Phase.1.Complexity Phase.2.Complexity Phase.3.Complexity Phase.4.Complexity Phase.5.Complexity Phase.6.Complexity Transaction.Feasibility Phase.0.Difficulty
1 B FS1 Low Low Medium Medium High High Medium 3860.694
2 I FS2 High High Medium Medium Medium Medium Medium 18102.778
3 I FS4 Medium Medium Medium Medium Medium Medium Medium 18102.778
4 B FS3 Low Low High High High High Medium 18102.778
5 B FS5 Medium Medium High Medium Medium Medium Medium 18102.778
在这种情况下,merge应该执行以下操作:
cost.table <- merge(
x = cost.table,
y = cost.approach.difficulty[c("Approach", "Difficulty", "Phase.0")],
by.x = c("Phase.0.Difficulty", "Approach"),
by.y = c("Difficulty", "Approach"), sort = FALSE
)
cost.table$Phase.0.Difficulty <- NULL
names(cost.table)[names(cost.table) == "Phase.0"] <- "Phase.0.Difficulty"
cost.table
Approach Identifier Phase.1.Complexity Phase.2.Complexity Phase.3.Complexity Phase.4.Complexity Phase.5.Complexity Phase.6.Complexity Transaction.Feasibility Phase.0.Difficulty
1 B FS1 Low Low Medium Medium High High Medium 3860.694
2 I FS2 High High Medium Medium Medium Medium Medium 18102.778
3 I FS4 Medium Medium Medium Medium Medium Medium Medium 18102.778
4 B FS3 Low Low High High High High Medium 18102.778
5 B FS5 Medium Medium High Medium Medium Medium Medium 18102.778
如果您想让它适用于可变数量的列,我建议您将成本表和查找表重塑为更标准的格式 首先,如果您以可复制的格式提供数据,那么回答这个问题会更容易:
# Create the example data
cost.table <- data.frame(
"Identifier" = c("FS1", "FS2", "FS3", "FS4", "FS5"),
"Phase.0.Difficulty" = c("Low", "High", "High", "High", "High"),
"Phase.1.Complexity" = c("Low", "High", "Low", "Medium", "Medium"),
"Phase.2.Complexity" = c("Low", "High", "Low", "Medium", "Medium"),
"Phase.3.Complexity" = c("Medium", "Medium", "High", "Medium", "High"),
"Phase.4.Complexity" = c("Medium", "Medium", "High", "Medium", "Medium"),
"Phase.5.Complexity" = c("High", "Medium", "High", "Medium", "Medium"),
"Phase.6.Complexity" = c("High", "Medium", "High", "Medium", "Medium"),
"Transaction.Feasibility" = c("Medium", "Medium", "Medium", "Medium", "Medium"),
"Approach" = c("B", "I", "B", "I", "B"),
stringsAsFactors = FALSE)
cost.approach.difficulty <- data.frame(
"Approach" = c("B", "B", "B", "I", "I", "I", "RV", "RV", "RV"),
"Difficulty" = c("High", "Low", "Medium", "High", "Low", "Medium", "High", "Low", "Medium"),
"Phase.0" = c(18102.778, 3860.694, 5323.694, 18102.778, 3860.694, 5323.694, 18102.778, 3860.694, 5323.694),
"Phase.1" = c(29481.67,15978.47, 24974.44, 74184.44, 26008.89, 41156.11, 28373.33, 14870.14, 22757.78),
"Phase.2" = c(29481.67, 11175.69, 15184.17, 29481.67, 11175.69, 15184.17, 29481.67, 11175.69, 15184.17),
"Phase.3" = c(11822.222, 7448, 9221.333, 44747.111, 16551.111, 22373.556, 44747.111, 16551.111, 22373.556),
"Phase.4" = c(30737.78, 12768, 15368.89, 69160, 35910, 44776.67, 69160, 44776.67, 44776.67),
"Phase.5" = c(21634.67, 11467.56, 12768, 45249.56, 16876.22, 23378.44, 45249.56, 16876.22, 23378.44),
"Phase.6" = c(12768, 11467.56, 12768, 32245.11, 14275.33, 16876.22, 32245.11, 14275.33, 16876.22),
stringsAsFactors = FALSE)
一旦这两个表采用标准格式,就可以调用merge:
要替换所有列,我将融合每个查找表,然后将它们全部绑定到一个查找表中。这样,您只需调用merge一次,就不必担心更换NAs。如果您想让它适用于不同数量的列,我建议您将成本表和查找表重新调整为更标准的格式 首先,如果您以可复制的格式提供数据,那么回答这个问题会更容易:
# Create the example data
cost.table <- data.frame(
"Identifier" = c("FS1", "FS2", "FS3", "FS4", "FS5"),
"Phase.0.Difficulty" = c("Low", "High", "High", "High", "High"),
"Phase.1.Complexity" = c("Low", "High", "Low", "Medium", "Medium"),
"Phase.2.Complexity" = c("Low", "High", "Low", "Medium", "Medium"),
"Phase.3.Complexity" = c("Medium", "Medium", "High", "Medium", "High"),
"Phase.4.Complexity" = c("Medium", "Medium", "High", "Medium", "Medium"),
"Phase.5.Complexity" = c("High", "Medium", "High", "Medium", "Medium"),
"Phase.6.Complexity" = c("High", "Medium", "High", "Medium", "Medium"),
"Transaction.Feasibility" = c("Medium", "Medium", "Medium", "Medium", "Medium"),
"Approach" = c("B", "I", "B", "I", "B"),
stringsAsFactors = FALSE)
cost.approach.difficulty <- data.frame(
"Approach" = c("B", "B", "B", "I", "I", "I", "RV", "RV", "RV"),
"Difficulty" = c("High", "Low", "Medium", "High", "Low", "Medium", "High", "Low", "Medium"),
"Phase.0" = c(18102.778, 3860.694, 5323.694, 18102.778, 3860.694, 5323.694, 18102.778, 3860.694, 5323.694),
"Phase.1" = c(29481.67,15978.47, 24974.44, 74184.44, 26008.89, 41156.11, 28373.33, 14870.14, 22757.78),
"Phase.2" = c(29481.67, 11175.69, 15184.17, 29481.67, 11175.69, 15184.17, 29481.67, 11175.69, 15184.17),
"Phase.3" = c(11822.222, 7448, 9221.333, 44747.111, 16551.111, 22373.556, 44747.111, 16551.111, 22373.556),
"Phase.4" = c(30737.78, 12768, 15368.89, 69160, 35910, 44776.67, 69160, 44776.67, 44776.67),
"Phase.5" = c(21634.67, 11467.56, 12768, 45249.56, 16876.22, 23378.44, 45249.56, 16876.22, 23378.44),
"Phase.6" = c(12768, 11467.56, 12768, 32245.11, 14275.33, 16876.22, 32245.11, 14275.33, 16876.22),
stringsAsFactors = FALSE)
一旦这两个表采用标准格式,就可以调用merge:
要替换所有列,我将融合每个查找表,然后将它们全部绑定到一个查找表中。这样,您只需调用merge一次,就不必担心更换NAs。最简单的答案似乎是: 使用“粘贴”组合查找列 使用“匹配”从查找表中查找行号 下面的代码用一行完成多列查找
cost.approach.difficulty$Phase.0[match(paste(cost.table$Approach,
cost.table$Phase.0.Difficulty), paste(cost.approach.difficulty$Approach,
cost.approach.difficulty$Difficulty))]
要在多个列之间循环,for循环可以正常工作
不幸的是,我希望有一个本机解决方案,可能需要一个列向量并将它们组合起来进行查找,但我还没有找到它。我将检查其他软件包,看看是否存在这样的功能。最简单的答案似乎是: 使用“粘贴”组合查找列 使用“匹配”从查找表中查找行号 下面的代码用一行完成多列查找
cost.approach.difficulty$Phase.0[match(paste(cost.table$Approach,
cost.table$Phase.0.Difficulty), paste(cost.approach.difficulty$Approach,
cost.approach.difficulty$Difficulty))]
要在多个列之间循环,for循环可以正常工作
不幸的是,我希望有一个本机解决方案,可能需要一个列向量并将它们组合起来进行查找,但我还没有找到它。我将检查其他软件包,看看是否存在这样的函数。在cost.approach.defficiency中用空格表示列名总是一个坏主意。它们可以用colnamescost.approach.defestion Beasterfield修复吗?我并不担心名称这只是一个例子,真正的问题是如何逐行遍历多个列,并基于从另一个数据帧中查找两列来替换值。你真的应该担心名称。如果没有其他原因的话,使用格式奇怪的示例数据名称或其他方式会让这里的人更难使用该示例数据来帮助回答您的问题。在cost.approach.defficiency中使用空白列名总是一个坏主意。它们可以用colnamescost.approach.defestion Beasterfield修复吗?我并不担心名称这只是一个例子,真正的问题是如何逐行遍历多个列,并基于从另一个数据帧中查找两列来替换值。你真的应该担心名称。如果没有其他原因的话,使用格式奇怪的示例数据名称或其他方式会让这里的人更难使用该示例数据来帮助回答您的问题。Beasterfield,这是一种方法,但如果有许多列,则可能会很难使用。在这种情况下,每个阶段都是.x。。列需要替换为查找值,而不仅仅是一列。我希望有个m
使用“匹配”在所有columns.Beasterfield中查找每个phase.x的对应值的方法,这是一种方法,但如果有多个columns.Beasterfield,则可能会很麻烦。在这种情况下,每个阶段都是.x。。列需要替换为查找值,而不仅仅是一列。我希望能找到一种方法,使用“匹配”在所有列中找到每个阶段.x的对应值。Schaun,这是一个解决方案,但非常混乱,也不太简洁。我发现简单地使用粘贴和匹配会更干净,但我很惊讶,使用查找表时没有本机支持。在我看来,使用不必要的重塑和合并数据帧是不必要的复杂。我将发布一个使用match的简单示例,但我真的希望有人知道一个更好的阅读、简洁和优雅的方法。成本.方法.难度$Phase.0[matchpastecost.table$方法,成本.表格$Phase.0.Demobility,pastecost.approach.Demobility$方法,成本.方法.难度$Phase]不雅观的数据组织通常需要不雅观的数据操作。您组织数据的方式很难创建简洁且可扩展的方法:查找表在不同的位置保留有关类型、大小和阶段的信息,但cost.table将类型和阶段组合在一起。一列一度量的组织减少了操作数据所需的代码总量。根据您现有的结构,简明的解决方案要求您事先知道所有列名,这意味着即使这也不是一个干净的解决方案。Schaunb,感谢您对演示数据的建设性批评!同时,最优雅的解决方案似乎是粘贴和匹配。我不是在批评你的演示数据,而是在解释为什么在这种情况下可能无法获得比你已经发现的更优雅的解决方案。Schaun,这是一个解决方案,但非常混乱,也不是很简洁。我发现简单地使用粘贴和匹配会更干净,但我很惊讶,使用查找表时没有本机支持。在我看来,使用不必要的重塑和合并数据帧是不必要的复杂。我将发布一个使用match的简单示例,但我真的希望有人知道一个更好的阅读、简洁和优雅的方法。成本.方法.难度$Phase.0[matchpastecost.table$方法,成本.表格$Phase.0.Demobility,pastecost.approach.Demobility$方法,成本.方法.难度$Phase]不雅观的数据组织通常需要不雅观的数据操作。您组织数据的方式很难创建简洁且可扩展的方法:查找表在不同的位置保留有关类型、大小和阶段的信息,但cost.table将类型和阶段组合在一起。一列一度量的组织减少了操作数据所需的代码总量。根据您现有的结构,简明的解决方案要求您事先知道所有列名,这意味着即使这也不是一个干净的解决方案。Schaunb,感谢您对演示数据的建设性批评!同时,最优雅的解决方案似乎是粘贴和匹配。我不是在批评您的演示数据,而是在解释为什么在这种情况下可能无法获得比您已经发现的更优雅的解决方案。
cost.approach.difficulty$Phase.0[match(paste(cost.table$Approach,
cost.table$Phase.0.Difficulty), paste(cost.approach.difficulty$Approach,
cost.approach.difficulty$Difficulty))]