knitr::opts_chunk$set(message = FALSE)
legcoplus
is an R package to reorganise and present data from the Hong Kong Legislative Council (LegCo)
APIs in a more useable manner. It provides functions that restructure data from multiple API requests to
enhance the efficiency of the use of LegCo's APIs.
This package requires the package legco
to fetch LegCo's open data.
To install legco
:
install.packages("devtools") devtools::install_github("elgarteo/legco")
install.packages("devtools") devtools::install_github("elgarteo/legcoplus")
And to load it before every use:
library(legcoplus)
The package contains the following functions:
answered_questions()
fetches more detailed information and the full text of questions
put on the government by any given LegCo member.legco_member_affiliation
contains the declared political affiliation and constituency of
every member in each term.member_voting_record()
returns the voting record in Council and committee meetings.search_committee()
searches committee by full or partial name of committee.search_division()
searches all division(s) (or votes) held in Council, House Committee,
Finance Committe and its subcommittees meetings on any given date, by any given
committee/subcommittee or during any given meeting slot.search_member()
searches everyone who speaks in LegCo with unique identifiers from
different LegCo APIs' databases or full or partial name.All functions can also be accessed with the prefix legco_
, e.g. legco_answered_questions()
and answered_questions()
return the same result.
LegCo APIs have an access limit of appraximately 1000 requests per hour per IP. As some of the functions
in this package (such as answered_questions()
) make multiple requests at a time, the limit can be reached
very easily. It is therefore advised to retrieve the data in smaller packets.
The function legco::questions()
returns only the subject of the question put on the government
but not the full text and the answering body:
legco::questions(rundown_id = 294209)
While the function answered_questions()
fetches the question text and other detailed information
as well:
w <- answered_questions(rundown_id = 294209)
Note that if verbose
is enabled (which is by default), multiple messages will be shown.
They are created when the function is making multiple requests to the APIs.
The actual number of records in the final output data frame is displayed in the last message.
For instance, it is 1 in the example above.
answered_questions()
returns the asking members of the main question and the supplementary
questions (if any):
# All asking members (including supplementary questions) legco::speakers(w$AskingSpeakerID) # The answering official of the question legco::speakers(w$AnsweringSpeakerID)
The full text of the main question, supplementary questions (if any), answers and miscellaneous conversations (e.g. some member rising to a point of order) are contained in lists:
# Excerpts of the question text w$Question[[1]][11] # Excerpts of the answer text w$Answer[[1]][8] # Excerpts of key appointment holders (e.g. President)/LegCo staff w$Misc[[1]][10]
It is also possible to fetch all questions raised by any given member and filter by parameters
that are supported by legco::questions()
.
# Search all written questions asked by SpeakerID 61 and MemberID 209 # from January to April 2019 in Chinese w <- answered_questions(speaker_id = 61, member_id = 209, from = "2019-01-01", to ="2019-04-30", type = "written", lang = "zh") w[, 1:5]
legco_member_affiliation
is a list containing data frames of the political affiliation and
constituency of every member in each LegCo term. The dataframes are named by the respective
TermID
they represent. For example, to fetch the data of the fifth term of LegCo:
# Political affiliation of the sixth term of LegCo w <- legco_member_affiliation[["5"]] head(w)
The function legco::voting_record()
of the Voting Results Database does not accept filtering
parameters of any unique identifier from other databases such as SpeakerID
, MemberID
,
CommitteeID
and SlotID
. Instead, it only takes the full Chinese names of LegCo members and
full English name of the committee. With the function member_voting_record()
, it is possible
to apply these idenitifers to search the voting results.
# Search the voting records of SpeakerID 102 and MemberID 910 # in CommitteeID 2567 since June 15, 2019. w <- member_voting_record(speaker_id = 102, member_id = 910, committee_id = 2567, from = "2019-06-15") head(w) # Search the voting records of meeting with SlotID w <- member_voting_record(slot_id = 177529) head(w)
The function search_committee()
allows searching committee with full or partial name of the committee:
# Search all Bills Committees established in the sixth term of LegCo w <- search_committee(search_term = "bills committee", term_id = 5) head(w[, 1:4])
By default, search_committee()
returns results with the exact match of the search term. It is
possible to disable exact matching so that the function returns results containing any of
the English words/Chinese characters in the search term:
# Search all committees with either "taxi" or "ferry" in the name w <- search_committee(search_term = "taxi ferry", exact = FALSE) w[, 1:4] # Search all committees with either "動" or "植" in the name w <- search_committee(search_term = "動植", exact = FALSE) head(w[, 1:4])
search_committee()
returns results containing the search term, including non-exact words.
For instance, records containing the term "taxi"
are included in the search result of
the search term "tax"
:
# Search result of "tax" w <- search_committee(search_term = "tax") w$NameEng
To have only exact words in the result, insert a space before and/or
after the word, e.g. " tax "
:
# Search result of " tax " w <- search_committee(search_term = " tax ") w$NameEng
legco::voting_record()
of the LegCo Voting Result Database does not support the use of
individual identifiers in search and the presentation of an index of votes.
With the function search_division()
, it is possible to search division(s) with CommitteeID,
and SlotID:
# Search votes conducted on April 3, 2019 by the Establishment Subcommittee w <- search_division(search_date = "2019-04-03", committee_id = 2943) w[, c(1:4, 24)] # Search vote conducted during a specific meeting w <- search_division(slot_id = 179602) w[, c(1:4, 24)]
By default, search_division()
returns an index list of votes only. To fetch the voting record of
each member:
# Search voting record of each member conducted during a specific meeting w <- search_division(slot_id = 179602, index = FALSE) head(w[, c(1:5, 28:29, 31)])
The unique identifiers of different LegCo databases are not interchangeable, for instance
SpeakerID
used in the Hansard Database and MemberID
used in the Schedule Database. search_member()
provides an easy way to work with SpeakerID
and MemberID
interchangeably:
# A combined list of all members from legco::speakers() and legco::member() w <- search_member() w[63:64, ] # Lookup the MemberID of SpeakerID 63 w <- search_member(speaker_id = 63) w$MemberID # Lookup the SpeakerID of MemberID 273 w <- search_member(member_id = 273) w$SpeakerID
search_member()
also allows searching by full or partial name in English or Chinese:
# Lookup members with "謙" in their names search_member(search_term = "謙") # Lookup members with "ting" in their names search_member(search_term = "ting")
The searching parameter of search_member()
has the same options with that of search_committee()
such as the exact search option. Refer here for detailed examples on how
to apply these options in your search.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.