utils.R 5.63 KB
Newer Older
1
2
3
lgb.is.Booster <- function(x) {
  lgb.check.r6.class(x, "lgb.Booster") # Checking if it is of class lgb.Booster or not
}
4

5
6
7
lgb.is.Dataset <- function(x) {
  lgb.check.r6.class(x, "lgb.Dataset") # Checking if it is of class lgb.Dataset or not
}
8

9
lgb.is.null.handle <- function(x) {
10
  is.null(x) || is.na(x)
11
}
Guolin Ke's avatar
Guolin Ke committed
12
13

lgb.encode.char <- function(arr, len) {
14

15
  if (!is.raw(arr)) {
16
    stop("lgb.encode.char: Can only encode from raw type") # Not an object of type raw
Guolin Ke's avatar
Guolin Ke committed
17
  }
18
  rawToChar(arr[seq_len(len)]) # Return the conversion of raw type to character type
19

Guolin Ke's avatar
Guolin Ke committed
20
21
}

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
lgb.last_error <- function() {
  # Perform text error buffering
  buf_len <- 200L
  act_len <- 0L
  err_msg <- raw(buf_len)
  err_msg <- .Call(
    "LGBM_GetLastError_R"
    , buf_len
    , act_len
    , err_msg
    , PACKAGE = "lib_lightgbm"
  )

  # Check error buffer
  if (act_len > buf_len) {
    buf_len <- act_len
    err_msg <- raw(buf_len)
    err_msg <- .Call(
      "LGBM_GetLastError_R"
      , buf_len
      , act_len
      , err_msg
      , PACKAGE = "lib_lightgbm"
    )
  }

  # Return error
  stop("api error: ", lgb.encode.char(err_msg, act_len))
}

Guolin Ke's avatar
Guolin Ke committed
52
lgb.call <- function(fun_name, ret, ...) {
53
  # Set call state to a zero value
54
  call_state <- 0L
55

56
  # Check for a ret call
Guolin Ke's avatar
Guolin Ke committed
57
  if (!is.null(ret)) {
58
59
60
61
62
63
64
    call_state <- .Call(
      fun_name
      , ...
      , ret
      , call_state
      , PACKAGE = "lib_lightgbm"
    )
Guolin Ke's avatar
Guolin Ke committed
65
  } else {
66
67
68
69
70
71
    call_state <- .Call(
      fun_name
      , ...
      , call_state
      , PACKAGE = "lib_lightgbm"
    )
Guolin Ke's avatar
Guolin Ke committed
72
  }
Guolin Ke's avatar
Guolin Ke committed
73
  call_state <- as.integer(call_state)
74
  # Check for call state value post call
75
  if (call_state != 0L) {
76
    lgb.last_error()
Guolin Ke's avatar
Guolin Ke committed
77
  }
Guolin Ke's avatar
Guolin Ke committed
78

79
  return(ret)
80

Guolin Ke's avatar
Guolin Ke committed
81
82
83
}

lgb.call.return.str <- function(fun_name, ...) {
84

85
  # Create buffer
86
  buf_len <- as.integer(1024L * 1024L)
87
  act_len <- 0L
Guolin Ke's avatar
Guolin Ke committed
88
  buf <- raw(buf_len)
89

90
  # Call buffer
Guolin Ke's avatar
Guolin Ke committed
91
  buf <- lgb.call(fun_name, ret = buf, ..., buf_len, act_len)
92

93
  # Check for buffer content
Guolin Ke's avatar
Guolin Ke committed
94
95
  if (act_len > buf_len) {
    buf_len <- act_len
96
97
    buf <- raw(buf_len)
    buf <- lgb.call(fun_name, ret = buf, ..., buf_len, act_len)
Guolin Ke's avatar
Guolin Ke committed
98
  }
99

100
101
  # Return encoded character
  return(lgb.encode.char(buf, act_len))
102

Guolin Ke's avatar
Guolin Ke committed
103
104
105
}

lgb.params2str <- function(params, ...) {
106

107
  # Check for a list as input
108
  if (!identical(class(params), "list")) {
109
110
    stop("params must be a list")
  }
111

112
  # Split parameter names
Guolin Ke's avatar
Guolin Ke committed
113
  names(params) <- gsub("\\.", "_", names(params))
114

115
  # Merge parameters from the params and the dots-expansion
Guolin Ke's avatar
Guolin Ke committed
116
117
  dot_params <- list(...)
  names(dot_params) <- gsub("\\.", "_", names(dot_params))
118

119
  # Check for identical parameters
120
  if (length(intersect(names(params), names(dot_params))) > 0L) {
121
122
123
124
125
126
127
    stop(
      "Same parameters in "
      , sQuote("params")
      , " and in the call are not allowed. Please check your "
      , sQuote("params")
      , " list"
    )
128
  }
129

130
  # Merge parameters
Guolin Ke's avatar
Guolin Ke committed
131
  params <- c(params, dot_params)
132

133
134
  # Setup temporary variable
  ret <- list()
135

136
  # Perform key value join
Guolin Ke's avatar
Guolin Ke committed
137
  for (key in names(params)) {
138

139
140
141
142
143
144
145
146
147
148
149
    # If a parameter has multiple values, join those values together with commas.
    # trimws() is necessary because format() will pad to make strings the same width
    val <- paste0(
      trimws(
        format(
          x = params[[key]]
          , scientific = FALSE
        )
      )
      , collapse = ","
    )
150
    if (nchar(val) <= 0L) next # Skip join
151

152
    # Join key value
Guolin Ke's avatar
Guolin Ke committed
153
    pair <- paste0(c(key, val), collapse = "=")
154
    ret <- c(ret, pair)
155

Guolin Ke's avatar
Guolin Ke committed
156
  }
157

158
  # Check ret length
159
  if (length(ret) == 0L) {
160
    return(lgb.c_str(""))
Guolin Ke's avatar
Guolin Ke committed
161
  }
162

163
164
165
  # Return string separated by a space per element
  return(lgb.c_str(paste0(ret, collapse = " ")))

Guolin Ke's avatar
Guolin Ke committed
166
167
168
}

lgb.c_str <- function(x) {
169

170
  # Perform character to raw conversion
Guolin Ke's avatar
Guolin Ke committed
171
  ret <- charToRaw(as.character(x))
172
  ret <- c(ret, as.raw(0L))
173
  ret
174

Guolin Ke's avatar
Guolin Ke committed
175
176
177
}

lgb.check.r6.class <- function(object, name) {
178

179
180
  # Check for non-existence of R6 class or named class
  all(c("R6", name) %in% class(object))
181

Guolin Ke's avatar
Guolin Ke committed
182
183
184
}

lgb.check.obj <- function(params, obj) {
185

186
  # List known objectives in a vector
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  OBJECTIVES <- c(
    "regression"
    , "regression_l1"
    , "regression_l2"
    , "mean_squared_error"
    , "mse"
    , "l2_root"
    , "root_mean_squared_error"
    , "rmse"
    , "mean_absolute_error"
    , "mae"
    , "quantile"
    , "huber"
    , "fair"
    , "poisson"
    , "binary"
    , "lambdarank"
    , "multiclass"
    , "softmax"
    , "multiclassova"
    , "multiclass_ova"
    , "ova"
    , "ovr"
    , "xentropy"
    , "cross_entropy"
    , "xentlambda"
    , "cross_entropy_lambda"
    , "mean_absolute_percentage_error"
    , "mape"
    , "gamma"
    , "tweedie"
218
219
220
221
222
    , "rank_xendcg"
    , "xendcg"
    , "xe_ndcg"
    , "xe_ndcg_mart"
    , "xendcg_mart"
223
  )
224

225
  # Check whether the objective is empty or not, and take it from params if needed
226
227
228
  if (!is.null(obj)) {
    params$objective <- obj
  }
229

230
  # Check whether the objective is a character
231
  if (is.character(params$objective)) {
232

233
    # If the objective is a character, check if it is a known objective
234
    if (!(params$objective %in% OBJECTIVES)) {
235

236
      # Interrupt on unknown objective name
237
      stop("lgb.check.obj: objective name error should be one of (", paste0(OBJECTIVES, collapse = ", "), ")")
238

Guolin Ke's avatar
Guolin Ke committed
239
    }
240

241
  } else if (!is.function(params$objective)) {
242

243
    # If objective is not a character nor a function, then stop
244
    stop("lgb.check.obj: objective should be a character or a function")
245

Guolin Ke's avatar
Guolin Ke committed
246
  }
247

248
249
  # Return parameters
  return(params)
250

Guolin Ke's avatar
Guolin Ke committed
251
252
253
}

lgb.check.eval <- function(params, eval) {
254

255
256
257
258
  # Check if metric is null, if yes put a list instead
  if (is.null(params$metric)) {
    params$metric <- list()
  }
259

260
  # If 'eval' is a list or character vector, store it in 'metric'
261
  if (is.character(eval) || identical(class(eval), "list")) {
262
    params$metric <- append(params$metric, eval)
263
  }
264

265
  return(params)
Guolin Ke's avatar
Guolin Ke committed
266
}