我正在从数据框中的混乱字符列中提取重量(克和公斤)和体积(毫升和公升)值,但无法排除总重量和体积。
一些示例数据如下:
df <-
rbind(data.frame(text = "199-50 150g4_qty_+ 200g4_qty_"),
data.frame(text = "chouffe/ 330ml*2_qty_+ 330ml*2_qty_+ 330ml*2_qty_"),
data.frame(text = "1000g( 500g+ 500g) _qty_"),
data.frame(text = "(abbott) 900g+50g 2 950g"),
data.frame(text = "1kg 2kg 3kg 1kg +2kg"),
data.frame(text = "200ml*18_qty_ +putzi 50ml"),
data.frame(text = "( 250ml*6_qty_+ 250ml*4_qty_+ 190ml*6_qty_+ 200ml*4_qty_)"),
data.frame(text = "128g+ 128g+ 128g 384g"))
通过对该站点的跟踪并经过反复试验,我编写了提取所需值以及一些我不想要的值的代码。
df1 <- regmatches(df$text, gregexpr("\\d+(ml|l|g|kg)", df$text))
df1 <- as.data.frame(t(sapply(df1, '[', seq(max(sapply(df1, length))))))
我得到:
V1 V2 V3 V4 V5
1 150g 200g NA NA NA
2 330ml 330ml 330ml NA NA
3 1000g 500g 500g NA NA
4 900g 50g 950g NA NA
5 1kg 2kg 3kg 1kg 2kg
6 200ml 50ml NA NA NA
7 250ml 250ml 190ml 200ml NA
8 128g 128g 128g 384g NA
大部分存在,但我想排除多余的值,例如重复(第5行)和总计(第3、4和8行)。最终结果应该是:
V1 V2 V3 V4
1 150g 200g NA NA
2 330ml 330ml 330ml NA
3 500g 500g NA NA
4 900g 50g NA NA
5 1kg 2kg NA NA
6 200ml 50ml NA NA
7 250ml 250ml 190ml 200ml
8 128g 128g 128g NA
我已经确定,要保留的值之间必须立即有一个+
。例如,第3行在500g和500g之间有一个+
,所以我想保留这两个值,但我不想保留1000g,因为在这和500g之间没有+
。同样,第8行384g之前也没有+
。
我只是不知道如何使用正则表达式来实现这一点,而又不能从太远的地方拿起+
。
答案 0 :(得分:1)
从多个角度看待这个问题后,我的解决方案是删除加号周围的空白:
df$text <- gsub("\\s+(?=\\+)|(?<=\\+)\\s+", "", df$text, perl=TRUE)
然后根据剩余空间将字符串拆分为元素:
var1 <- strsplit(df$text, "\\s+")
然后使用grepl
选择包含加号的元素,从而删除不包含+
的所有元素:
var2 <- lapply(var1, function(x) x[grepl("\\+", x, perl=TRUE)])
最后使用先前创建的代码来保留所需的字符串:
df1 <- regmatches(var2, gregexpr("\\d+(ml|l|g|kg)", var2))
df1 <- as.data.frame(t(sapply(df1, '[', seq(max(sapply(df1, length))))))
这使我非常接近,可能需要对边缘进行一些修补,以处理异常情况。