我有一个带有+3000个字符串的data.frame列,我想将它们分开,但它们是不规则的,尽管有一个模式。以下是一些示例,以及我希望它们转换成的内容。
00700 / Z14P120:xhkg
03988 / Z14C3.2:xhkg
图6A / F15C0.905:xcme
ADS / X14P56:xeur
AX1 / X14P375:xams
BIDU / 28X14C250:xcbf
ES / F15C1960:xcme
FUR / M16P8:xams
00700 | P | 120个
03988 | C | 3.2
6A | C | 0.905
ADS | P | 56个
AX1 | P | 375个
BIDU | C | 250个
ES | C | 1960年
FUR | P | 8
我认为这涵盖了每个子字符串的所有可能长度和值类型。
第一个新列应覆盖输入列,其他两列应覆盖同一data.frame中的现有列空白
另一个复杂因素是data.frame行已经正确格式化,但是有一列标识不是的行。下面是.CSV输出表的一部分。
最终解决方案: 由于NA,类和行号注册的问题,更换现有列中的值比预期更困难。因此,我最终以相当丑陋和低效的方式创建临时列并替换整个列。 然而,Ananda Mahto提供的代码确实非常出色。
ETO <- as.array(data_results$InstrumentSymbolCode)
ETO <- do.call(rbind,
strsplit(gsub("(.*)/[A-Z0-9]+?([A-Z])([0-9\\.-]+)?:.*",
"\\1NONSENSESPLIT\\2NONSENSESPLIT\\3", ETO),
"NONSENSESPLIT", fixed = TRUE))
ETO[data_results$ProductCategoryID!=9] <- ""
temp1 <- array(0,nrow(ETO))
temp2 <- array(0,nrow(ETO))
temp3 <- array(0,nrow(ETO))
for (i in 1:nrow(ETO)){
if (data_results$ProductCategoryID[i]==9) {
temp1[i] <- ETO[i,1]
temp2[i] <- ETO[i,2]
temp3[i] <- ETO[i,3]
} else {
temp1[i] <- as.character(data_results$InstrumentSymbolCode[i])
temp2[i] <- as.character(data_results$PutCall[i])
temp3[i] <- data_results$Strike[i]
}
}
data_results$InstrumentSymbolCode<-as.character(temp1)
data_results$PutCall <- temp2
data_results$Strike <- temp3
答案 0 :(得分:1)
你可以使用一些正则表达式和strsplit
,也许是这样的:
do.call(rbind,
strsplit(gsub("(.*)/[A-Z0-9]+?([A-Z])([0-9\\.-]+)?:.*",
"\\1NONSENSESPLIT\\2NONSENSESPLIT\\3", mydf$v1),
"NONSENSESPLIT", fixed = TRUE))
# [,1] [,2] [,3]
# [1,] "00700" "P" "120"
# [2,] "03988" "C" "3.2"
# [3,] "6A" "C" "0.905"
# [4,] "ADS" "P" "56"
# [5,] "AX1" "P" "375"
# [6,] "BIDU" "C" "250"
# [7,] "ES" "C" "1960"
# [8,] "FUR" "P" "8"
目前还不清楚您希望在原始数据中替换这些值的位置/方式。
示例数据:
mydf <- data.frame(v1 = c("00700/Z14P120:xhkg", "03988/Z14C3.2:xhkg",
"6A/F15C0.905:xcme", "ADS/X14P56:xeur", "AX1/X14P375:xams",
"BIDU/28X14C250:xcbf", "ES/F15C1960:xcme", "FUR/M16P8:xams"))