用于数据框行名的正则表达式解决方案

时间:2019-04-19 15:21:42

标签: r regex

我有一个从函数返回的数据帧,如下所示:

example

我的目标是将其变成这样:

df <- data.frame(data = c(1,2,3,4,5,6,7,8))
rownames(df) <- c('firsta','firstb','firstc','firstd','seconda','secondb','secondc','secondd')

firsta  1
seconda 5
firstb  2
secondb 6

基本上,问题在于行名中包含我无法舍弃的信息,因为否则就无法区分列值。

1 个答案:

答案 0 :(得分:4)

这是一个简单的long-to-wide conversion;缺点是我们需要通过适当地分割字符串从行名生成键变量。

在您提供的数据中,行名由“位置”(即“ first”,“ second”)和id(即“ a”,“ b”)的缩写组成,并附加在结束。这种结构使拆分变得复杂:理想情况下,您将使用分隔符(即first_afirst_b)来使分隔变得明确。如果没有分隔符,我们唯一的选择是在位置上分割,但这要求分割位置与字符串的开头或结尾之间的距离为固定距离。

在您的示例中,id始终是最后一个字符,因此我们可以将-1传递给sep的{​​{1}}参数,以分隔最后一个字符作为ID列。如果并非总是如此,那么您将需要一个更复杂的解决方案来解析行名。

将行名转换为“ position”和“ id”列后,使用separate将position列扩展为宽格式很简单:

spread

如果行ID的长度可能可变,则上述解决方案将无效。如果“位置”值已知且数量有限,则可以使用正则表达式解决方案来拆分行名:

在这里,我们通过匹配包含所有可能值的正则表达式(library(tidyverse) df %>% rownames_to_column('row') %>% separate(row, into = c('num', 'id'), sep = -1) %>% spread(num, data) id first second 1 a 1 5 2 b 2 6 3 c 3 7 4 d 4 8 是OR运算符)来提取位置值。

我们通过将相同的正则表达式放入positive lookahead operator中来匹配“ id”值。此正则表达式将匹配在位置值立即出现的1个或多个小写字母。这种方法的缺点是,您需要在正则表达式中指定“位置”的所有可能值-如果有很多选择,则可能很快变得太长且难以维护:

|