Фон . Я использую R для ввода данных в рабочую книгу Excel, чтобы рабочая книга могла рассчитать результат. Я делаю это в R, потому что я хочу ввести много разных наборов данных, и это займет много времени, чтобы сделать это вручную в реальной книге Excel. Для каждого нового «набора» введенных данных (= 1 строка во входном файле) я затем извлекаю вычисленные значения из раздела «Результаты» рабочей книги обратно в R.
Итак, у меня есть три элемента:
- Входные данные (
CFTData
- это указано в приведенном ниже коде). Каждая строка в df представляет собой новый «набор» входных данных. - Рабочая книга Excel (CoolFarmTool.xlsm), которая выполняет вычисления (можно загрузить из https://github.com/alexavarah/Carbon/blob/master/CoolFarmTool.xlsm)
- Сценарий R для итеративного ввода каждого «набора» входных данных в рабочую книгу и извлечения результатов, создавая фрейм данных результатов.
Проблема заключается в том, что для В некоторых ячейках значения из моих входных данных (CFTData
), похоже, не были успешно введены в целевую ячейку Excel. Эти ячейки имеют проверку данных и позволяют только записи из списка. Не всегда происходит сбой: например, данные успешно вводятся в целевую ячейку E13 на листе 3 рабочей книги, несмотря на то, что эта ячейка имеет проверку данных списка; но данные, кажется, не записываются в ячейку E12 на листе 4, который также имеет проверку данных списка. Если бы действительно успешно ввел мои входные данные в ячейку E12 на листе 4, то всякий раз, когда значение * отличалось от «Нет», я ожидал бы ненулевой результат в «C изменениях запасов» столбец данных фрейма данных. Однако я только получаю ноль. Если я открою электронную таблицу Excel и вручную изменю ячейку E12 на листе 4 на что-то отличное от «Нет» [пробел после текста является преднамеренным], я получу ненулевой результат в соответствующей ячейке на листе результатов (лист 9 , ячейка H19).
* Другие возможные значения: «Уменьшено до обычного» или «Обычное до уменьшенного» * 1026 *
Я пытался поиграться с форматом входных данных, но безрезультатно. , Я пытался очистить данные проверки в листе Excel, но это тоже не имело никакого значения.
Кто-нибудь знает, что может происходить?
Код выглядит следующим образом:
library("XLConnectJars")
library("XLConnect")
CFT <- XLConnect::loadWorkbook(".../CoolFarmTool.xlsm")
setStyleAction(CFT,XLC$"STYLE_ACTION.NONE")
CFTData <- data.frame(fieldname=c("A","A","A"),scenario=c("test","test","test"),year=c(2020,2020,2020),rotation=c(1,2,3),fieldID=c("A","A","A"),product=c("Winter wheat","Winter wheat","Oilseed Rape"),
production_area=c(7.2,7.2,7.2),finished_product_from_production_area=c(61.920,55.728,25.200),climate=c("Temperate","Temperate","Temperate"),avg_annual_temp=c(10,10,10),
croptype=c("Winter wheat","Winter wheat","Other"),soiltexture=c("Fine","Fine","Fine"),SOM_integer=c(5.848,5.848,5.848),SOM=c("5.16 < SOM <= 10.32","5.16 < SOM <= 10.32","5.16 < SOM <= 10.32"),
soilmoisture=c("Moist","Moist","Moist"),soildrainage=c("Good","Good","Good"),pHvalue=c(7,7,7),pH=c("5.5 < pH <= 7.3","5.5 < pH <= 7.3","5.5 < pH <= 7.3"),
fertiliser1=c("Ammonium nitrate - 35% N","Ammonium nitrate - 35% N","Ammonium nitrate - 35% N"),applicationrate=c(240,240,190),fertiliser_spraydays=c(3,3,2),
pesticide_applicns=c(10.2576,10.2576,2.0000),tillage_changes_dropdown=c("Conventional to Reduced","No ","No "),tillage_changes=c("Conventional to Reduced","No ","No "),
tillage_changes_time=c(1,1,1),tillage_changes_pc=c(100,100,100),residue_management=c("Left on field; Incorporated or mulch","Left on field; Incorporated or mulch","Left on field; Incorporated or mulch"),
residue_incorporation_dropdown=c("stopped incorporating","no change","no change"),residue_incorporation=c("stopped incorporating","no change","no change"),
chisel_plough=c(0,0,0),disc_gang=c(0,0,0),disc_harrow=c(1,2,0),field_cultivator_ridger=c(0,0,0),grain_drill=c(0,0,0),grain_drill_notill=c(1,1,0),
moldboard_plough=c(0,0,0),roller_harrow=c(0,1,0),roller_packer=c(2,2,1),rotary_hoe_bed_tiller=c(0,0,0),subsoiler=c(0,0,1),tine_harrow=c(0,0,0),spraydays_BGgly=c(4,4,3)
)
writeWorksheet(CFT," - United Kingdom", 2, 7, 5, header = FALSE)
writeWorksheet(CFT,"Metric", 2, 8, 5, header = FALSE)
writeWorksheet(CFT,"hectares", 2, 12, 6, header = FALSE)
writeWorksheet(CFT,"tonnes", 2, 14, 6, header = FALSE)
CFT_all <- function(DF, subtract = "nothing"){
if(subtract == "herb fuel"){
DF$applicationrate = 0
}else if(subtract == "herb manuf"){
DF$pesticide_applicns = 0
}else if(subtract == "till"){
DF[,which(colnames(CFTData)=="chisel_plough"):which(colnames(CFTData)=="tine_harrow")] = 0
}else{
DF = DF
} # Subset function if want to leave out any of the sources of emissions e.g. fertiliser use.
output = data.frame(fix.empty.names = FALSE)
for (a in 1:nrow(DF)) {
X = DF[a,]
X <- t(X) # Transposes X to allow it to be merged with the lookup table
FieldID = X["fieldID",]
print.default(a) # prints 1 for the first round of the loop (except that it doesn't...), then 2 etc.
X <- merge(X, lookup, by = "row.names") # Gives destinations of each variable
X <- X[!is.na(X$DestCol),]
X <- setNames(X, c("Variable","Value","DestSheet","DestCol","DestRow"))
writeWorksheet(CFT,"N", 3, 19, 6, header = FALSE) # Sets fertiliser nutrient
writeWorksheet(CFT,"Ammonium nitrate - 35% N", 3, 19, 5, header = FALSE) # Sets fertiliser type
for(i in 1:nrow(X)){
# For loop reads each row value and writes it to the destination cell as found from the lookup table
b = X$Value[i]
c = X$DestSheet[i]
d = X$DestRow[i]
e = X$DestCol[i]
writeWorksheet(CFT, b, c, d, e, header = FALSE)
}
setForceFormulaRecalculation(CFT, sheet = c(2:18), TRUE)
results = readWorksheet(CFT,9,13,8,27,8)
results[is.na(results)] = 0
results <- setNames(results, "Value")
results <- data.frame(c(FieldID,results$Value[1],results$Value[2],results$Value[4],results$Value[6],results$Value[10],results$Value[14]),fix.empty.names = FALSE) # Extracts desired results
output <- rbind(output,t(results))
}
output <- setNames(output,c("Field ID","Fertiliser production (kgC02eq/ha)","Field N20 (kgC02eq/ha)","Pest (kgC02eq/ha)","C stock changes (kgC02eq/ha)","Till (kgC02eq/ha)","Total (kgC02eq/ha)"))
return(output)
}
lookup = setNames( data.frame(matrix( data = NA,
nrow = ncol(CFTData[which(colnames(CFTData)=="fieldname"):which(colnames(CFTData)=="spraydays_BGgly")]),
ncol = 3)),
c("DestSheet","DestCol","DestRow"))
row.names(lookup) = names(CFTData[which(colnames(CFTData)=="fieldname"):which(colnames(CFTData)=="spraydays_BGgly")])
# column in CFTdata: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
lookup$DestCol = c( NA, NA, "e", NA, NA, "e","e","e","e","e","e","e", NA, "e","e","e", NA, "e","e","g","e","e",NA, "e","f","g","e",NA, "e","e","e","e","e","e","e","e","e","e","e","e","e","e")
lookup$DestSheet = as.numeric(c( NA, NA, 2, NA, NA, 2, 2, 2, 2, 2, 3, 3, NA, 3, 3, 3, NA, 3, 3, 3, 6, 3, NA, 4, 4, 4, 3, NA, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6))
lookup$DestRow = as.numeric(c( NA, NA, 6, NA, NA, 11, 12, 14, 17, 18, 5, 12, NA, 13, 14, 15, NA, 16, 19, 19, 61, 27, NA, 12, 12, 12, 31, NA, 16, 36, 38, 39, 41, 42, 43, 46, 49, 50, 51, 54, 56, 60))
myLetters <- letters[1:26]
lookup$DestCol <- match(lookup$DestCol, myLetters)
outputdata <- CFT_all(CFTData)
(Извините, я не мог понять, как загрузить книгу Excel прямо в R из моего Github.)