关于数据框的gsubfn

时间:2018-03-27 12:42:13

标签: r regex gsubfn

在给定替换列表的情况下搜索并替换数据框中的元素。

代码:

testing123tmp <- data.frame(x=c("it's", "not", "working"))
testing123tmp$x <- as.character(testing123tmp$x)
tmp <- list("it's" = "hey", "working"="dead")
apply(testing123tmp,2,function(x) gsubfn('.', tmp, x))

预期输出:

      x        
[1,] hey   
[2,] not  
[3,] dead

我目前的输出:

     x        
[1,] "it's"   
[2,] "not"    
[3,] "working"

一直在寻找chartr和gsub中可能的解决方案,但是想要简单(短编码),这样的操作需要多个gsub。此外,我的变量tmp可以缩放到多对替换,以便:

tmp <- list("it's" = "hey", 
            "working"="dead",
            "other" = "other1",
             .. = .. ,
             .. = .. ,
             .. = .. )

编辑/更新#1:

  • 还想在上面的gsubfn和数据框架中找到解决方案

2 个答案:

答案 0 :(得分:4)

问题是:

  • 点只匹配一个字符,因此它永远不会匹配整个字符串,除非整个字符串有一个字符,因此tmp中的名称不会匹配。使用".*"匹配整个字符串。如果你想匹配单词,即在x的每个组件中可能有几个由空格分隔的单词,那么例如x的一个组件可能是"it's not",我们仍然希望匹配it's然后使用"\\S+"。还有其他可以想象的变化,这给出了一个包含其中许多变化的框架。

  • gsubfn的第三个参数可能已经是一个向量,gsubfn将迭代它,因此不必使用apply。 (它仍然适用于apply,但这是不必要的。)

  • 将数据框中的所有内容放在一个简单的方法是使用transform,如下所示(或者也可以在gsubfn包中使用transform2)。 x会自动引用x数据框中的testing123tmp列,而transform将生成一个不会覆盖原始数据框的新数据框。如果您希望保留这些内容,请将transform的结果分配给新名称,或者如果您要覆盖testing123tmp,请将其分配回testing123tmp

  • 我们可以使用stringsAsFactors = FALSE来避免生成字符列。

    testing123tmp <- data.frame(x=c("it's", "not", "working"), stringsAsFactors = FALSE)
    

因此我们可以将代码缩减为:

transform(testing123tmp, y = gsubfn(".*", tmp, x))

提供以下data.frame:

        x    y
1    it's  hey
2     not  not
3 working dead

如果我们要覆盖x列而不是保留单独的输入和输出列,我们可以在x = ...语句中使用transform而不是y = ...

答案 1 :(得分:2)

你可以写

gsubfn(".*", tmp, testing123tmp$x)
# [1] "hey"  "not"  "dead"

然后

testing123tmp$x <- gsubfn(".*", tmp, testing123tmp$x)

至于您的方法,不需要apply因为gsubfn在该参数上进行了矢量化,问题是仅匹配. ---一个符号,而{ {1}}和it's的长度各不相同。

但是,如果要用另一个单词替换一个单词,则不需要正则表达式。例如,

working

应该更快。如果任务涉及更多,那么我想

idx <- testing123tmp$x %in% names(tmp)
testing123tmp$x[idx] <- unlist(tmp)[testing123tmp$x[idx]]

应该比library(stringr) str_replace_all(testing123tmp$x, unlist(tmp)) # [1] "hey" "not" "dead" 更强大,因为您不需要处理gsubfn等模式。