R语言比对两个xts时间序列列表 识别差异与不一致同名序列
问题背景
现有两个存储时间序列对象的列表list_1和list_2,list_1中的时间序列可能存在于list_2中,也可能不存在。两个列表中单条时间序列的格式示例如下:
2007-07-03 1270.9060 2007-07-04 1267.8440 2007-07-05 1269.7260 2007-07-06 1270.7180 2007-07-07 1270.6210 2007-07-08 1270.5230 2007-07-09 1272.6600 2007-07-10 1275.3270 2007-07-11 1269.2300 2007-07-12 1267.7230 2007-07-13 1271.5470 2007-07-14 1271.4500 2007-07-15 1271.3520 2007-07-16 1271.2550 2007-07-17 1269.3970 2007-07-18 1258.4610 2007-07-19 1259.3700 2007-07-20 1272.2220 2007-07-21 1272.1250 2007-07-22 1272.0270 2007-07-23 1279.5210 2007-07-24 1283.7750 2007-07-25 1292.8030 2007-07-26 1279.0540
需要实现两项功能:
- 识别仅存在于单个列表中的时间序列
- 针对两个列表共有的同名时间序列,识别对应序列内容是否完全一致
现有代码与问题
功能1实现(已正常运行)
识别单列表独有时间序列的代码可正常输出结果:
names1 = sort(names(list_1)) names2 = sort(names(list_2)) c(setdiff(names1,names2),setdiff(names2,names1))
功能2实现(存在异常)
识别同名序列是否一致的初始代码如下:
quantq = list() for (i in names1) { if (i %in% names(2)) { quantq[i] = names(all(list_1[[i]] != list_2[[i]])) } }
预期quantq列表存储names1中与list_2对应序列内容不一致的时间序列名称,但实际运行输出为连续数字索引,异常输出示例:
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [19] 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 [37] 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 [55] 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 [73] 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 [91] 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 [109] 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 [127] 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 [145] 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
问题原因
你的判断正确,初始代码存在3个核心错误:
- 笔误:
i %in% names(2)写法错误,数字2不存在names属性,正确应为i %in% names2 - 逻辑错误:
all(list_1[[i]] != list_2[[i]])仅当两个序列所有元素都不相等时才返回TRUE,无法判断序列整体是否一致;逐元素对比也无法校验时间索引、对象属性是否匹配,判断xts序列完全一致应该用identical()函数 - 赋值错误:
names(all(...))会尝试取单个逻辑值的名称,逻辑值本身无名称属性,就会返回序列的位置索引,最终输出连续数字;另外给列表按名称赋值应该用[[而非[,避免存储结构异常。
修正代码
# 先提取两个列表共有的序列名称 common_names <- intersect(names1, names2) quantq <- list() for (i in common_names) { # 同时对比序列值、时间索引、对象属性,完全一致才判定为匹配 if (!identical(list_1[[i]], list_2[[i]])) { quantq[[i]] <- i } } # 如果不需要保留list结构,直接输出不一致的名称向量,可以简化为: # mismatch_names <- common_names[!sapply(common_names, function(n) identical(list_1[[n]], list_2[[n]]))]
测试样例验证
提供的测试子集ex1(对应list_1)和ex2(对应list_2)结构如下:
- ex1包含序列:COP、CLP、CLF
- ex2包含序列:CLP、CLF、MXN、PEN
- 共有序列为CLP、CLF,两个序列在ex1和ex2中完全一致
运行修正代码后quantq返回空列表,符合预期;如果修改任意一个共有序列的值或索引,代码会正确捕获对应名称存入结果。
测试用样例数据代码:
ex1 = list(COP = structure(c(1877.5, 1892.5, 1910, 1912.4, 1901, 1902.5, 1901, 1905.85, 1917, 1921), class = c("xts", "zoo"), index = structure(c(946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 947548800, 947635200, 947721600, 947808000), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L)), CLP = structure(c(528, 529.43, 530, 527, 524.55, 522.5, 522.5, 519.53, 517.05, 515.67), class = c("xts", "zoo"), index = structure(c(946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 947548800, 947635200, 947721600, 947808000), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L)), CLF = structure(c(0.036074341203342, 0.0358335681613619, 0.0360059735494465, 0.0358781557617286, 0.035702777866953, 0.0356677208908729, 0.0355560203401352, 0.035958251000177, 0.035870302585323, 0.0357348617586791 ), class = c("xts", "zoo"), index = structure(c(1080864000, 1081123200, 1081209600, 1081296000, 1081382400, 1081728000, 1081814400, 1081900800, 1081987200, 1082073600), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L), .Dimnames = list(NULL, NULL))) ex2 = list(CLP = structure(c(528, 529.43, 530, 527, 524.55, 522.5, 522.5, 519.53, 517.05, 515.67), class = c("xts", "zoo"), index = structure(c(946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 947548800, 947635200, 947721600, 947808000), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L)), CLF = structure(c(0.036074341203342, 0.0358335681613619, 0.0360059735494465, 0.0358781557617286, 0.035702777866953, 0.0356677208908729, 0.0355560203401352, 0.035958251000177, 0.035870302585323, 0.0357348617586791 ), class = c("xts", "zoo"), index = structure(c(1080864000, 1081123200, 1081209600, 1081296000, 1081382400, 1081728000, 1081814400, 1081900800, 1081987200, 1082073600), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L), .Dimnames = list(NULL, NULL)), MXN = structure(c(9.505, 9.5713, 9.571, 9.58, 9.565, 9.47, 9.5125, 9.522, 9.4875, 9.4503 ), class = c("xts", "zoo"), index = structure(c(946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 947548800, 947635200, 947721600, 947808000), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L)), PEN = structure(c(3.52, 3.5205, 3.519, 3.509, 3.511, 3.509, 3.508, 3.509, 3.5005, 3.4875), class = c("xts", "zoo"), index = structure(c(946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 947548800, 947635200, 947721600, 947808000), tzone = "UTC", tclass = "Date"), .Dim = c(10L, 1L)))
内容的提问来源于stack exchange,提问作者Valeria Arango
相关产品推荐
相关产品推荐

