Selecionar membros da amostra.r 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. ## Selecionar membros da amostra: Sorteia unidades da população suficientes para a quota proporcional de acordo com o gênero sexual
  2. ## Copyright (c) 2018 Adonay Felipe Nogueira <https://libreplanet.org/wiki/User:Adfeno>
  3. ## This program is free software: you can redistribute it and/or
  4. ## modify it under the terms of the GNU General Public License as
  5. ## published by the Free Software Foundation, version 3 of the
  6. ## License.
  7. ## This program is distributed in the hope that it will be useful, but
  8. ## WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. ## General Public License for more details.
  11. ## You should have received a copy of the GNU General Public License
  12. ## along with this program. If not, see
  13. ## <https://www.gnu.org/licenses/>.
  14. ## Lê os caminhos dos arquivos de entrada e saída.
  15. args <- commandArgs(trailingOnly = TRUE)
  16. arquivo_de_entrada_csv <- args[1]
  17. arquivo_de_saida_csv <- args[2]
  18. ## Lê o arquivo de entrada. `check.names = FALSE' faz os nomes das
  19. ## colunas serem importados com espaços, `na.strings = ""' faz com que
  20. ## as células vazias sejam realmente consideradas como valores em falta
  21. ## pelo interpretador GNU R.
  22. academicos <- read.csv(arquivo_de_entrada_csv,
  23. check.names = FALSE,
  24. na.strings = "")
  25. ## Não queremos selecionar um membro da população que fora impedido,
  26. ## mas ao mesmo tempo não queremos selecionar uma amostra maior do que
  27. ## a quota que precisamos. `is.na' retorna resultado verdadeiro (TRUE)
  28. ## se a célula avaliada possuir valor faltante, esta verificação é
  29. ## necessária pois do contrário, qualquer outra tentativa de conseguir
  30. ## subconjuntos resultaria em um comportamento no qual estas células
  31. ## seriam descartadas ou todas as outras seriam apresentadas com
  32. ## valores faltantes; `==' retorna verdadeiro (TRUE) caso os objetos da
  33. ## esquerda e da direita sejam iguais;`!=' espera pelo inverso; `|' e
  34. ## `&' são "ou" e "e" lógicos, respectivamente; parêntesis são
  35. ## agrupadores; `!' inverte o resultado lógico de uma operação.
  36. filtro_para_excluir_impedidos <-
  37. paste('is.na(academicos$"Situação na pesquisa") ',
  38. '| (academicos$"Situação na pesquisa" != "Selecionado" ',
  39. '& academicos$"Situação na pesquisa" != "Ausente" ',
  40. '& academicos$"Situação na pesquisa" != "Recusou" ',
  41. '& academicos$"Situação na pesquisa" != "Participou")',
  42. sep = "")
  43. filtro_para_contar_participantes <-
  44. paste('! is.na(academicos$"Situação na pesquisa") ',
  45. '& (academicos$"Situação na pesquisa" == "Selecionado" ',
  46. '| academicos$"Situação na pesquisa" == "Participou")',
  47. sep="")
  48. ## `ceiling()' calcula o teto de um número real; `unique()' retorna os
  49. ## valores removendo suas duplicatas; `length()' retorna o número
  50. ## total de itens em uma lista.
  51. quota_proporcional.F <-
  52. ceiling(length(unique(academicos[academicos$"Gênero sexual" == "F",
  53. "Nome"])) *
  54. (length(unique(academicos[academicos$"Gênero sexual" == "F",
  55. "Nome"])) /
  56. length(unique(academicos[,
  57. "Nome"]))))
  58. quota_proporcional.M <-
  59. ceiling(length(unique(academicos[academicos$"Gênero sexual" == "M",
  60. "Nome"])) *
  61. (length(unique(academicos[academicos$"Gênero sexual" == "M",
  62. "Nome"])) /
  63. length(unique(academicos[,
  64. "Nome"]))))
  65. ## `factor()' remove os níveis/valores que eram possíveis antes da
  66. ## criação do subconjunto, mas que não são mais presentes no novo
  67. ## conjunto; `(eval(parse(text=...)))' converte uma cadeia de
  68. ## caracteres em parâmetros ou objetos para o GNU R e seus comandos.
  69. nomes_disponiveis.F <-
  70. factor(unique(academicos[academicos$"Gênero sexual" == "F"
  71. & (eval(parse(text=filtro_para_excluir_impedidos))),
  72. "Nome"]))
  73. nomes_disponiveis.M <-
  74. factor(unique(academicos[academicos$"Gênero sexual" == "M"
  75. & (eval(parse(text=filtro_para_excluir_impedidos))),
  76. "Nome"]))
  77. quantidade_faltando.F <-
  78. quota_proporcional.F -
  79. length(unique(academicos[academicos$"Gênero sexual" == "F"
  80. & (eval(parse(text=filtro_para_contar_participantes))),
  81. "Nome"]))
  82. quantidade_faltando.M <-
  83. quota_proporcional.M -
  84. length(unique(academicos[academicos$"Gênero sexual" == "M"
  85. & (eval(parse(text=filtro_para_contar_participantes))),
  86. "Nome"]))
  87. ## `sample()' retira amostras de uma população, o que por padrão no
  88. ## GNU R é feito de forma que os membros já selecionados sejam
  89. ## retirados da probabilidade dos demais sorteios; `length()' retorna
  90. ## o total de itens em uma lista; `if() {} else {}' faz uma
  91. ## comparação, e caso seja verdade, usa o conteúdo do primeiro par de
  92. ## chaves, se não: usa o segundo; `<=' compara numericamente se o lado
  93. ## esquerdo é menor ou igual ao direito. Essa combinação entre `if()
  94. ## {} else {}', `<=' e as demais variáveis é necessário pois quando
  95. ## `sample()' opera retirando os já selecionados das probabilidades
  96. ## subsequentes, esta função não pode receber um número de
  97. ## vagas/requerimentos maior que a "população" informada.
  98. nomes_selecionados.F <-
  99. sample(nomes_disponiveis.F,
  100. if(quantidade_faltando.F <= length(nomes_disponiveis.F)) {
  101. quantidade_faltando.F}
  102. else {
  103. length(nomes_disponiveis.F)})
  104. nomes_selecionados.M <-
  105. sample(nomes_disponiveis.M,
  106. if(quantidade_faltando.M <= length(nomes_disponiveis.M)) {
  107. quantidade_faltando.M}
  108. else {
  109. length(nomes_disponiveis.M)})
  110. ## Para todos os membros da população que foram sorteados, insere-se
  111. ## na célula da coluna "Situação na pesquisa" o status de
  112. ## "Selecionado". Ao invés de calcular os índices em partes anteriores
  113. ## deste script, usa-se `%in%' para comparar cada célula da coluna
  114. ## "Nome" com as listas de nomes selecionados, de modo que um nome em
  115. ## várias linhas também seja selecionado.
  116. academicos[academicos$"Nome" %in%
  117. nomes_selecionados.F
  118. | academicos$"Nome" %in%
  119. nomes_selecionados.M,
  120. "Situação na pesquisa"] <- "Selecionado"
  121. ## Escreve o resultado no arquivo de saída. `na = ""' faz as células
  122. ## com valores faltantes serem exportadas com campo vazio; `row.names
  123. ## = FALSE' exclui a coluna que contém o nome das linhas.
  124. write.csv(academicos, file = arquivo_de_saida_csv, na = "", row.names = FALSE)