我在 F48 中以 {year, value} 的形式将数据括在花括号中,如下所示:
我想编写一个公式,从 2017 年的值中减去 1990 年的值,然后将差额除以 1990 年的值,但我不知道如何做。
我认为最简单的方法是使用 INDEX 和 MATCH 函数。在需要结果的单元格中,输入以下公式:
=(INDEX(karnkraft,MATCH(2017,karnkraft,0),2)-INDEX(karnkraft,MATCH(1990,karnkraft,0),2))/INDEX(karnkraft,MATCH(1990,karnkraft,0),2)
此公式将在 karnkraft 数据中查找 2017 年的值并减去 1990 年的值,然后将该差值除以 1990 年的值。不会吗?
更进一步,如何以以下方式获取形式为 {year, value} 的新列中的值:
- 商将与 1990 年和 2017 年的值相乘以获得新的最小值和最大值。
- 我们将使用最大值和最小值作为参考,以{年份,值}的形式获取 1990 年至 2017 年期间这些数字之间的随机值。
- 我将针对不同的数据进行冲洗并重复。
答案1
问题应修改为:
如何从 Excel 中的字符串中提取名称/值对?
=MID(C1,
SEARCH("{"&A1, C1)+LEN(A1)+2,
SEARCH("}", C1, SEARCH("{"&A1, C1))-1-SEARCH("{"&A1, C1)-LEN(A1)-2)
解释
假设单个单元格“C1”中有以下数据/字符串
karnkraft = {{1990, 2000.642591},{1991, 2096.356868},{1992, 2112.277946},{1993, 2185.016841},{1994, 2226.050783},{1995, 2641.599256},{2004, 2757.124087},{2005, 2746.479825},{2008, 2737.860822},{2009, 2575.664304},{2016, 2612.83283},{2017, 2322.592422}, {1996, 2407.002623}, {1997, 2390.480054}, {1998, 2431.571247}, {1999, 2524.546817}, {2000, 2580.976669}, {2001, 2653.821898}, {2002, 2696.204132}, {2003, 2769.046942}, {2006, 2803.605088}, {2007, 2699.245242}, {2010, 2767.507814}, {2011, 2651.771616}, {2012, 2472.44864},{2013,2491.705601},{2014,2541.027341},{2015,2635.561104}};
您想要从 NAME VALUE 对中提取一个 VALUE,其中 NAME 是年份。
在单元格“A1”中,我们将输入要查找的名称(年份),在本例中为“1991”
然后,我们要找到 NAME 放在“A1”中的位置(本例中为“1991”)。为了找到 NAME '1991',我们搜索“{1991”。我们包括“{”,因为 VALUES 也是数字,我们不希望出现误报。没有 VALUES 以“{”开头。
=SEARCH("{"&A1, C1)
=SEARCH("{1991",C1)
=33
- 为了确定我们的 VALUE 最左边的位置,我们使用步骤 #2 (33) 中 NAME 的位置,并将该数字增加其长度 (LEN) 以及任何额外的空格、标点符号等。
=33 + length of 'A1' + 2 // + 2 char for ", "
=33 + len(A1) + 2
=33 + 4 + 2
=39
Position: 33 39
String: ...{1991, 2096.356868}...
Count: 123456
- 为了获取 VALUE 最右边的位置。我们搜索紧跟步骤 #2 中 NAME 位置的“}”的位置 (33)。
=SEARCH("}", C1, 33)
=51
Position: 33 51 // next "}"
String: ...{1991, 2096.356868}...
- 我们现在可以通过从步骤 #4 的最右边位置 (51) - 1 中减去步骤 #3 的最左边位置 (39) 来确定 VALUE 的长度 (LEN) (因为我们不想要跟在 VALUE 后面的“}”:
=51-1-39 // left-most - 1 - right-most
=11 // LEN of VALUE
Position: 33 51 // next "}"
String: ...{1991, 2 0 9 6 . 3 5 6 8 6 8 }...
1 2 3 4 5 6 7 8 9 10 11
- 剩下的就是将结果插入 MID 并提取我们的值:
=MID(text, start_num, num_chars)
=MID(C1, 39, 11)
=2096.356868
- 您可以使用辅助单元格来重复公式的部分,但是没有任何辅助单元格的完整公式是:
=MID(text,
start_num,
num_chars)
=MID(C1,
SEARCH("{"&A1, C1)+LEN(A1)+2,
SEARCH("}", C1, SEARCH("{"&A1, C1))-1-SEARCH("{"&A1, C1)-LEN(A1)-2)
=MID(C1,
33+LEN("1991")+2,
SEARCH("}", C1, SEARCH("{1991", C1))-1-SEARCH("{1991", C1)-LEN("1991")-2)
=MID(C1,
33+4+2,
51-1-33-4-2)
=MID(C1,
39,
51-1-33-4-2)
=2096.35686
更好的数据存储方式
鉴于这是一个电子表格,将数据对存储在表中更有意义,并且有助于提取和其他计算。
以下是我推测的两个单元格中一半的数据的示例,应用了 3 种不同的排序。数据是可访问的,您可以执行大量计算(包括索引/匹配)。
答案2
据我了解,数据以“karnkraft”开头,然后是一个空格,“=”和括号值前的另一个空格,如果您有新的文本函数,以下内容将起作用:
=LET(YearEnd, 2017, YearStart, 1990,
String, SUBSTITUTE(LEFT(RIGHT(F48,LEN(F48)-14),LEN(RIGHT(F48,LEN(F48)-14))-2),"}, {","ϣ"),
Table, VALUE(TEXTSPLIT(String,", ","ϣ",TRUE,1)),
End, VLOOKUP(YearEnd,Table,2,FALSE), Start, VLOOKUP(YearStart,Table,2,FALSE),
End - Start
)
有人可能会想知道为什么VLOOKUP
使用而不是(通常)更好的XLOOKUP
(或替换的函数对和它有与此处相同的问题INDEX/MATCH
)。原因是Table
公式内部虚拟创建的是单个项目,因此引用它XLOOKUP
的查找数组很容易,但引用它的返回数组却不是。VLOOKUP
让您考虑整个实体,因为您返回其中的一列,而不是引用的列。
当然,关键在于TEXTSPLIT
让字符串更美观。不过这需要准备,所以字符串是通过用 删除前导字符(包括“{{”)形成的RIGHT
。(并且,如果删除的“14”不是 而是 ,则需要对其进行更改karnkraft = {{
。karnkraft={{
)然后用 删除结尾的“}}” LEFT
。
最后,由于将其拆分成两列的行所需的分隔符都包含,
(逗号空格)(一个是逗号空格,另一个是用“}{”括起来的),因此其中一个需要替换为一些唯一的且不包含 的分隔符,
。因此是SUBSTITUTE
。
所有这些都是LET
为了便于阅读。如果一个人也没有,那么只需要在变量出现的地方替换变量的公式即可。这看起来会很复杂,很麻烦,但其实是一样的。(我通常会说“大多数”,因为LET
允许进行一次计算,然后结果在公式中使用多次,这可以导致更快的公式,在大量使用时,可以使电子表格的响应速度更快。但在这种情况下,实际上没有什么会被使用超过一次,所以它的主要优点是可读性。)
如果我误解了数据源,它就无法工作。但很可能您可以对其进行小范围的修改,并使其在实际数据集上工作。