-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathget_ly_bills.R
210 lines (192 loc) · 6.68 KB
/
get_ly_bills.R
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#' @title Fetch and Parse Legislative Yuan Bills 取得並解析立法院議案資料
#'
#' @description
#' Retrieves bill information from the Legislative Yuan API with comprehensive filter options.
#' Supports filtering by term, session, bill type, status, and other attributes.
#' Returns both metadata and detailed bill information.
#'
#' @param page integer. Page number for pagination (default: 1)
#' @param per_page integer. Number of items per page (default: 20)
#' @param term integer. Legislative term, e.g., 11
#' @param session integer. Legislative session period, e.g., 2
#' @param bill_type string. Type of bill:
#' - "法律案" (Law Bill)
#' - "中央政府總預算案" (Central Government Budget Bill)
#' - "預(決) 算決議案" (Budget/Final Account Resolution)
#' - "定期報告" (Regular Report)
#' - "行政命令(層級)" (Administrative Order)
#' - "院內單位來文" (Internal Document)
#' @param current_status string. Current bill status, e.g., "排入院會"
#' @param process_status string. Status in process flow, e.g., "排入院會 (交內政委員會)"
#' @param proposer string. Bill proposer name
#' @param cosigner string. Bill cosigner name
#' @param source string. Source of bill, e.g., "委員提案"
#' @param bill_id string. Bill ID number
#' @param law_id string. Related law ID number
#' @param meeting_code string. Meeting code, e.g., "院會-11-2-3"
#' @param show_progress logical. Whether to display progress bar (default: TRUE)
#'
#' @return A list containing:
#' \itemize{
#' \item metadata - List of pagination info and applied filters
#' \item bills - Data frame of bill details
#' }
#'
#' @examples
#' # Get law bills
#' bills <- get_ly_bills(
#' term = 11,
#' bill_type = "法律案",
#' show_progress = TRUE
#' )
#'
#' # Get budget bills
#' bills <- get_ly_bills(
#' term = 11,
#' bill_type = "中央政府總預算案",
#' show_progress = TRUE
#' )
#'
#' # Get administrative orders
#' bills <- get_ly_bills(
#' term = 11,
#' bill_type = "行政命令(層級)",
#' show_progress = TRUE
#' )
#'
#' @importFrom httr GET content status_code
#' @importFrom jsonlite fromJSON
#' @importFrom utils txtProgressBar setTxtProgressBar
#' @encoding UTF-8
#' @export
get_ly_bills <- function(
page = 1,
per_page = 20,
term = NULL, # Legislative term
session = NULL, # Session period
bill_type = NULL, # Bill type
current_status = NULL, # Current status
process_status = NULL, # Process flow status
proposer = NULL, # Proposer name
cosigner = NULL, # Cosigner name
source = NULL, # Bill source
bill_id = NULL, # Bill ID
law_id = NULL, # Law ID
meeting_code = NULL, # Meeting code
show_progress = TRUE # Show progress bar
) {
# Construct API base URL
base_url <- "https://v2.ly.govapi.tw/bills"
# Build query parameters
query_params <- list(
page = page,
per_page = per_page,
屆 = term,
會期 = session,
議案類別 = bill_type,
議案狀態 = current_status,
"議案流程.狀態" = process_status,
提案人 = proposer,
連署人 = cosigner,
提案來源 = source,
議案編號 = bill_id,
法律編號 = law_id,
會議代碼 = meeting_code
)
# Remove NULL parameters
query_params <- query_params[!sapply(query_params, is.null)]
# Show initial progress message
if (show_progress) {
cat("Fetching data...\n")
}
# Send GET request to API
response <- httr::GET(
base_url,
query = query_params
)
# Check response status
if (httr::status_code(response) != 200) {
stop("API request failed with status code: ", httr::status_code(response))
}
# Show data received message
if (show_progress) {
cat("Data received successfully, processing...\n")
}
# Parse JSON response
content <- httr::content(response, "text", encoding = "UTF-8")
data <- jsonlite::fromJSON(content, simplifyVector = FALSE)
# Extract metadata
metadata <- list(
total = data$total,
total_page = data$total_page,
current_page = data$page,
per_page = data$limit,
filters_used = query_params
)
# Show processing message with total count
if (show_progress) {
cat(sprintf("Found %d bills, converting...\n", length(data$bills)))
}
# Process bills if available
if (length(data$bills) > 0) {
# Initialize progress bar
if (show_progress) {
pb <- utils::txtProgressBar(min = 0, max = length(data$bills), style = 3)
}
# Convert bills to data frame
bills_list <- lapply(seq_along(data$bills), function(i) {
bill <- data$bills[[i]]
# Update progress bar
if (show_progress) {
setTxtProgressBar(pb, i)
}
# Extract bill fields with NULL handling
data.frame(
議案編號 = ifelse(is.null(bill$議案編號), NA_character_, bill$議案編號),
議案名稱 = ifelse(is.null(bill$議案名稱), NA_character_, bill$議案名稱),
議案狀態 = ifelse(is.null(bill$議案狀態), NA_character_, bill$議案狀態),
議案類別 = ifelse(is.null(bill$議案類別), NA_character_, bill$議案類別),
提案來源 = ifelse(is.null(bill$提案來源), NA_character_, bill$提案來源),
會期 = ifelse(is.null(bill$會期), NA_integer_, as.integer(bill$會期)),
屆 = ifelse(is.null(bill$屆), NA_integer_, as.integer(bill$屆)),
最新進度日期 = ifelse(is.null(bill$最新進度日期), NA_character_, bill$最新進度日期),
提案人 = if (!is.null(bill$提案人)) paste(unlist(bill$提案人), collapse = ", ") else NA_character_,
提案單位 = ifelse(is.null(bill$`提案單位/提案委員`), NA_character_, bill$`提案單位/提案委員`),
url = ifelse(is.null(bill$url), NA_character_, bill$url),
stringsAsFactors = FALSE
)
})
# Close progress bar
if (show_progress) {
close(pb)
cat("\nConversion complete!\n")
}
# Combine all data frames
bills_df <- do.call(rbind, bills_list)
} else {
# Create empty dataframe with correct structure if no bills found
bills_df <- data.frame(
議案編號 = character(),
議案名稱 = character(),
議案狀態 = character(),
議案類別 = character(),
提案來源 = character(),
會期 = integer(),
屆 = integer(),
最新進度日期 = character(),
提案人 = character(),
提案單位 = character(),
url = character(),
stringsAsFactors = FALSE
)
}
# Show completion message
if (show_progress) {
cat(sprintf("Processing complete! Total bills processed: %d\n", nrow(bills_df)))
}
# Return results
return(list(
metadata = metadata,
bills = bills_df
))
}