你好我有以下問題
說我有一個檔案base.R
x <- 1
# comment
y <- Y ~ X1
X2
# comment 2
z <- function(x) {
x 1
}
t <- z(x)
和另一個檔案override.R
x <- 2
y <- Y ~ X1 X3
我的目標是創建另一個檔案new.R,該檔案基本上base.R被override.R
x <- 2
# comment
y <- Y ~ X1 X3
# comment 2
z <- function(x) {
x 1
}
t <- z(x)
顯然,如果其中的所有運算式base.R都是 1 襯里,我將能夠使用sed,但不幸的是,事實并非如此。請注意,lhs <- rhs如果理想情況下也可以正常作業,我只需要它來進行分配lhs = rhs。
編輯:以上是我實際問題的最小化
uj5u.com熱心網友回復:
如果您可以接受被剝奪的評論,那么這對您來說可能就足夠了:
開頭base.R:
x <- 1
# comment
y <- Y ~ X1
X2
# comment 2
z <- function(x) {
x 1
}
t <- z(x)
和override.R:
x <- 2
y <- Y ~ X1 X3
我們可以運行:
base <- parse("base.R")
override <- parse("override.R")
base_assignment <-
sapply(base, function(z) as.character(z[[1]]) %in% c("<-", "="))
base_lhs <- mapply(function(assigned, z) as.character(z[[2]]),
base_assignment, base)
override_assignment <-
sapply(override, function(z) as.character(z[[1]]) %in% c("<-", "="))
override_lhs <- mapply(function(assigned, z) as.character(z[[2]]),
override_assignment, override)
matches <- match(base_lhs, override_lhs)
base[which(!is.na(matches))] <- override[na.omit(matches)]
writeLines(paste(do.call(c, lapply(base, deparse)), collapse = "\n"), "new.R")
現在我們new.R有了
x <- 2
y <- Y ~ X1 X3
z <- function(x) {
x 1
}
t <- z(x)
對于對話,為了保留評論,我們可能需要使用getParseData:
- 迭代
$parent,$id以便我們的$line1參考可以組合,將其存盤line1到一個新變數中(因為我們需要從getParseData(base); - 查找每個運算式后面
$token == "SYMBOL"存在的所有參考。在我們遇到的情況下,或者更像是一個挑戰,$token == "LEFT_ASSIGN"這開始有點阻礙它(因為假定的符號順序發生了變化);"EQ_ASSIGN""RIGHT_ASSIGN" - 第 2 步幫助我們找到發生分配的物件名稱,我們用它來比較
base/override處理; - 替換每個版本的決議幀的子集;
- 找到一種方法將生成的決議幀重新組合到源檔案中。
我沒有時間試圖讓它優雅/穩健地作業,所以我提供它作為保留評論所需努力的一個例子。
我建議,如果您的意圖是允許覆寫運算式的單個源檔案,那么保持base.R不變(如您的問題)并創建一個臨時 new.R使用、獲取和丟棄是有意義的,在這種情況下,它的注釋是相切的。
uj5u.com熱心網友回復:
有時,通過重新定義問題本身,可以使難題變得更容易。在下文中,我們提出了一些方法,其中一些具有特別簡單的實作。在 (7) 中,我們提供了執行問題要求的代碼,但您可能更愿意稍微更改問題并在我們提供的其他解決方案之一中使用更簡單的代碼。
1)省略base.R和連接檔案中的前幾行我們將假設override.R應該覆寫base.R中的所有內容,直到base.R中要覆寫的最后一條陳述句。覆寫陳述句之后的 base.R 中的注釋以及 override.R 中的任何注釋都將保留。因此,在示例comments 2中將保留comments并將被覆寫,但如果需要可以復制,override.R這似乎是合理的,因為您不能假設適用于 base.R 分配的注釋也適用于 override.R 。
確定noverride.R 中的陳述句數。然后決議base.R并找到第一行之前的最后一個行號不被覆寫,ix。然后在以該行號結尾的行中找到最后一個非注釋行號mx。現在寫出 override.R ,然后mx是 base.R 的第一行以外的所有內容。在下面的代碼中,將 stdout() 替換為所需的輸出檔案名稱,例如"outfile.R".
library(utils)
n <- length(parse("override.R"))
g <- getParseData(parse("base.R"))
ix <- g$line1[grep("^0", g$parent)][n 1] - 1
baseLines <- readLines("base.R")
is_comment <- grepl("^\\s*#", head(baseLines, ix))
mx <- max(which(!is_comment))
overrideLines <- readLines("override.R")
writeLines(c(overrideLines, tail(baseLines, -mx)), stdout())
給予:
x <- 2
y <- Y ~ X1 X3
# comment 2
z <- function(x) {
x 1
}
t <- z(x)
2)注釋掉而不是省略一種替代方法是注釋掉覆寫的行而不是省略它們。writeLines我們可以通過用下面的陳述句替換陳述句來輕松地做到這一點。這將允許人們同時查看 base.R 中的注釋(如果有)和 override.R 中的注釋。
writeLines(c(overrideLines, sub("^", "# ", head(baseLines, mx)),
tail(baseLines, -mx)), stdout())
給予:
x <- 2
y <- Y ~ X1 X3
# x <- 1
# # comment
# y <- Y ~ X1
# X2
# comment 2
z <- function(x) {
x 1
}
t <- z(x)
3) 分隔符如果您控制 base.R,那么更簡單的方法是標記要覆寫的部分的結尾。假設我們將#--- 單獨放在base.R 中要覆寫的部分和其余部分之間的一行上。然后我們有以下更簡單的:
overrideLines <- readLines("override.R")
baseLines <- readLines("base.R")
ix <- grep("#---", baseLines)[1]
writeLines(c(overrideLines, tail(baseLines, -ix)), stdout())
4)存在或可能,在base.R中,檢查是否x已經定義,如果沒有則只定義它。同上y。然后只需連接兩個檔案或一個接一個地采購。
if (!exists("x")) x <- ...whatever...
if (!exists("y")) y <- ...whatever...
5) 函式另一種可能性是定義一個函式,其默認值是 base.R 中 x 和 y 的當前值。然后我們可以將其稱為 f() 來獲取默認值或指定它們。
f <- function(x = ..., y = ...) { ...base.R code except x and y ...}
6) 省略 base.R 中的定義 也許最簡單的替代方法就是省略 base.R 中的定義,并且每次運行都有一個 override.R 是首先獲取的或連接的。
7) 保留 base.R 評論這個問題可以解決問題,但它有點復雜,您可能更喜歡其他解決方案之一。
library(codetools)
library(utils)
baseLines <- readLines("base.R")
overrideLines <- readLines("override.R")
p_o <- parse("override.R")
g_o <- getParseData(p_o)
locals_o <- findLocalsList(p_o)
ipos <- sapply(locals_o, function(x) which(g_o$text == x)[1]-1)
DFo <- cbind(g_o[ipos, ], var = names(ipos))
p_b <- parse("base.R")
g_b <- getParseData(p_b)
ipos <- sapply(locals_o, function(x) which(g_b$text == x)[1]-1)
DFb <- data.frame(g_b[ipos, ], var = names(ipos), row.names = NULL)
o <- order(-DFb$line1)
DFb <- DFb[o, ]
newLines <- baseLines
for(i in 1:nrow(DFb)) {
j <- match(DFb$var[i], DFo$var)
newLines <- append(newLines,
overrideLines[DFo$line1[j]:DFo$line2[j]], DFb$line2[i])
newLines <- newLines[-(DFb$line1[i]:DFb$line2[i])]
}
writeLines(newLines, stdout())
給予:
x <- 2
# comment
y <- Y ~ X1 X3
# comment 2
z <- function(x) {
x 1
}
t <- z(x)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/527265.html
標籤:r解析
