【问题标题】:Cumulative application of a gsub sequence in RR中gsub序列的累积应用
【发布时间】:2021-04-11 13:46:35
【问题描述】:

我正在做一个处理国际象棋游戏的项目。在对数据进行一些处理后,我需要获取特定位置的 FEN (https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation) 符号。我已经为每个 FEN 编码编写了代码,但是我很难对表示未占用的连续方块数的字符进行编码。

以如下FEN码为例:

"rnbq1rk1/pppp1ppp/1b11pn11/11111111/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"

每个 1 代表棋盘内的一个空方格。因此,例如:11111111 告诉我们棋盘内的这一行没有被棋子占据。

问题是,使用 FEN 作为输入来绘制棋盘的 R 包不喜欢这种表示法,他们想要更活跃的原始表示法,其中所有 1s 都由一个字符表示:所有这些连续字符的总和1s。对于前面的示例,这将是:

"rnbq1rk1/pppp1ppp/1b2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"

请注意,例如,11111111 序列被替换为 8,即所有连续 1s 的总和

我尝试使用mapplygsub 来完成替换,但它一次一个地迭代应用模式替换对的字符串。结果如下:

代码:

pattern <- c("11111111","1111111","111111","111111","1111","111","11")
replacement <- c("8","7","6","5","4","3","2")
FENCodeToBeChanged  <-  "rnbq1rk1/pppp1ppp/1b11pn11/11111111/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
mapply(gsub,pattern,replacement,FENCodeToBeChanged)

结果:

                                                                              11111111 
  "rnbq1rk1/pppp1ppp/1b11pn11/8/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2" 
                                                                           1111111 
 "rnbq1rk1/pppp1ppp/1b11pn11/71/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2" 
                                                                            111111 
"rnbq1rk1/pppp1ppp/1b11pn11/611/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2" 
                                                                            111111 
"rnbq1rk1/pppp1ppp/1b11pn11/511/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2" 
                                                                              1111 
       "rnbq1rk1/pppp1ppp/1b11pn11/44/11PP4/41NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2" 
                                                                               111 
   "rnbq1rk1/pppp1ppp/1b11pn11/3311/11PP31/311NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2" 
                                                                                11 
       "rnbq1rk1/pppp1ppp/1b2pn2/2222/2PP22/221NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"

如您所见,它一次进行一个替换,对于下一个模式替换对,它从原始字符串开始,它不会按照我在模式中指定的顺序累积它们 - 替换向量。

我已经尝试了herehere 描述的策略,但它们也没有奏效。正如它在最后一个链接中提到的那样,我试图不惜一切代价避免循环 gsubs 来完成工作,因为它似乎效率很低。

关于如何进行的任何想法?

谢谢!

【问题讨论】:

    标签: r vectorization gsub mapply fen


    【解决方案1】:

    mapply 的问题在于,它会为每次替换查找 FEN 字符串的新副本,这不是您需要的。我认为你可以使用Reduce 的心态:

    (顺便说一句,您的“5”模式有 6 个,这解决了这个问题。)

    pattern <- c("11111111","1111111","111111","11111","1111","111","11")
    Reduce(function(txt, ptn) gsub(ptn, as.character(nchar(ptn)), txt), pattern, init=FENCodeToBeChanged)
    # [1] "rnbq1rk1/pppp1ppp/1b2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
    

    为了能够减少多个参数需要一些工作,通常沿着一个对列表或类似的列表进行迭代。对于 this 问题,很容易用它的长度替换模式,而不是包含另一个字符串向量,ergo nchar(ptn)。 (从技术上讲,as.character(.) 不是必需的,因为gsub 会隐式转换它,但我想有点“声明性”,因为这正是我想要的。R 中有许多工具在这种方式下不太确定(例如, ifelse). 风格。)

    【讨论】:

    • 非常感谢@r2evans,您的建议正是我想要的!不知道 Reduce ,在对字符串/值进行多次修改时,对于累积值或结转结果似乎非常有用。
    猜你喜欢
    • 2014-09-29
    • 2022-08-18
    • 1970-01-01
    • 2022-01-13
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多