Skip to content
This repository was archived by the owner on Jun 21, 2025. It is now read-only.

Commit 529d615

Browse files
storopoliNMLebedevElias-Nodah-pgy
authored
[PT] dataframes_pt (#4)
* added pt markdown files for dataframes chapter * updated config.toml * Update dataframes_pt.md * Update dataframes_pt.md * Update dataframes_pt.md * Update dataframes_pt.md * Update dataframes_pt.md * Update dataframes_indexing_pt.md * Update dataframes_indexing_pt.md * Update dataframes_indexing_pt.md * Update dataframes_indexing_pt.md * Update dataframes_load_save_pt.md * Update dataframes_load_save_pt.md * Update dataframes_load_save_pt.md * Update dataframes_load_save_pt.md * Update dataframes_select_pt.md * Update dataframes_select_pt.md * Update dataframes_load_save_pt.md * Update dataframes_select_pt.md * Update dataframes_select_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update dataframes_join_pt.md * Update why_julia_pt.md (#6) * Update why_julia_pt.md * Update contents/why_julia_pt.md Co-authored-by: Jose Storopoli <[email protected]> * revisão técnica - Henrique Pougy 3. Sugestão: Mais idiomático 24. Importante manter o termo técnico query 28. Higest rating: nota mais alta. Melhor classificado implica calculo de media. 32. Sugestão. 42. Sugestão. 52. Desambiguação. Notas escolares fica mais claro que apenas notas. 68. Recomendamos trazudir column-major por formato colunar. 74. Sugestão. 99. Sugestão. 117. Sugestão: mais usual na área usar "em formato de tabela". 123. Importante manter should = deveriam, porque usando variaveis globais eles podem ser acessados de outras formas (esse é o problema). 125. Mudassemos o conteúdo: isso é importante, pois o problema aqui é alterar as coluans que estão como variáveis globais. 136. Destruídas ao invés de desaparecem: as variáveis são destruídas mesmo. Desaparecem dá a entender que elas apenas saem de escopo mas continuam existindo. 138. Crase. 139. Qual seria a saida, nao onde ela estaria. 148. Sugestão. 156. Sugestão. 166. Lhe daremos: mais idiomático. 168. Sugestão. 170. Sugestão. 171. Sugestão. 179. O termo técnico é envelopar. 186. '''' 188. Use case = caso de uso. * Update dataframes_transform_pt.md * Update dataframes_groupby_combine_pt.md * Revisao Técnica - Henrique Pougy 4. Sugestão. 11. Sugestão. 18. Sugestão. 25. Correção de typo, faltou uma palavra na frase. 26. Correção de typo. 28. Don't get this description = não entendeu essa descrição. 29. Operação foi realizada no dataset chamado notas, não nas notas do dataset. 45. Typo. 45. Traduzindo set intersection por intersecção de conjuntos 49. Traduzindo inner e outer para ficar mais claro ao leitor brasileiro. 64. Sugestão. 96. No jargao usamos o termo em ingles left join, sugiro manter ele junto à tradução. 96. Dataframe à esquerda, não à esquerda do Dataframe 127. Sugestão. 135. Elementos que não estão no dataframe, não que não são o dataframe. * Update contents/dataframes_pt.md * Update dataframes_pt.md AVISO: a versão original possuí algumas notas que não estão presentes na versão em português, no entanto essas notas parecem ser todas sobre os autores discutindo sobre como montar o capítulo 50 - Vírgula não necessária e erro de coerência, se são "próximas seções", nós "mostraremos" (futuro) e não "mostramos" (passado ou presente indicativo) 148 - AVISO: a tradução adicionou um "podemos também", mas parece sintáticamente correto para ter coerência no português 187~192 - AVISO: em português, o brinquedo "building blocks" é chamado de "blocos de montar", "bloquinhos de montar" ou "monta-monta", enquanto chamar ele de "Lego" é mais intuitivo, esse é o nome de uma marca e não do brinquedo, então não é arriscado acabar com um problema de direitos autorais? OBS: eu tenho noção de que se desse problema vocês poderiam facilmente declarar e conseguir um fair use, dado que ele está sendo usado como um exemplo para ensino, mas mesmo assim é bom evitar né * Revisão Técnica - Henrique 3. Sugestão. 5. Mudança de ordem para ficar mais idiomático. 11. Adicionei rápida menção que quando o locale é BR o separador é ponto e virgula. 36. Sugestão, mudei a ordem. 54. Correção: what if = e se. 55. Typo. 56. Sugestão. 80. Tab, neste contexto, é tabulação. 110. Sugestão. 112. Loading = carregar ou o carregamento. 113. Concordância. 113. Sugestão. 125. Column types = tipos de dados das colunas 153. Concordância e mudança de ordem para ficar idiomático. 156. A frase estava repetida. 158. Faltou traduzir uma sentença. 176. Sugestão. 182. Sheet = aba do excel. 204. Customizações ao invés de personalizações. 205. Documentação do módulo * Revisão Técnica - Henrique 3. Concordância, plural. 15. much like an, quando usado para verbo, é 'de modo muito parecido com' 22. Which = o que/o qual 22. 31. 'o comando' para ficar mais idiomático. 51. Faltou traduzir uma sentença. 57. See = veja, faltou traduzir. 58. Concordância: uma das estruturas de dados é capaz de criar mapeamentos. 64. Loops trough = itera por, ou então 'percorre' para ficar menos jargão 73. Typo. 74. Traduzindo filter por filtrar para auxiliar o leitor lusófono. 79. Faltou traduzir uma linha, traduzi ela. 80. Faltou traduzir uma linha. 84-86. Traduzi um parágrafo. Parei de fazer a revisão pois vi que a tradução ainda não está finalizada. * Revisão Técnica - Henrique 27. Sugestão. 41. Sugestão. 48. Retornado é o termo técnico. 50. Sugestão, para concordância de número. 69. Sugestão, para concordância de gênero: entendi que o sujeito é "as maneiras". 96. Sugestão. 101 - 103. Comentário tinha sido traduzido em parte, retornei ao inglês. 106. Sugestão para evitar repetições. 110. Typo. 116. O termo técnico para sorting é ordenação. 119. Comentário traduzido por engano, voltei ao inglês. 127. Sorting = ordenação. 133. ''' 143. Age é o nome da coluna. 151. Sugestão - regência. 157. Ordem da variável. 164. A função categorical pertence ao modulo CategoricalArrays.jl. 165. Sorting = ordenação. Sugestao. 167. O nome da coluna é age. 183. Mantendo a referência ao nome da coluna/variável. * Revisão Técnica - Henrique Pougy 4. Comentário traduzido, retornei ao inglês. 7. Sugestão. 13. Sugestão. 24. Sugestão. 35. Sugestão. 36. Sugestão. 38. Sugestão, para deixar claro que é a minilinguagem do módulo. 39. Sugestão. 78. Sugestão: capable -> robustas. 82. No jargão utiliza-se o termo em inglês left join mesmo. 102-103. Comentário traduzido, retornei ao inglês. * Revisão técnica - Elias 1 - Erro de digitação, Carrgar = Carregar 22 - Erro de digitação, carregue-lo = carregá-lo 159 - Erro de coesão, "para nós inspecionarmos e entendermos", e não "para nós inspecionar e entender" 204 - Necessário vírgula antes de "mas" 204 - Sugestão: no original, em "more powerful usage and customizations" a segunda palavra estar no plural pode implicar volatilidade na qualidade da primeira, então "usos mais poderosos e customizações" fica melhor que "um uso mais poderoso e customizações", a não ser que realmente só tenha um único uso mais poderoso * Revisão técnica - Elias 96 - O título original está em maiúsculo e o termo técnico mais utilizado é "dados faltantes" 118~120 - AVISO: esse comentário realmente faz parte do texto? Ou é só uma nota dos autores discutindo? * Revisão técnica - Elias 9 - Erro de coesão, se você "se pegar dando voltas" e por isso "precisará de um dos joins abaixo", então você estava "comparando-o com outros dados" 36 - Erro de coerência, "se você não ainda não compreendeu" não faz sentido 37 - Erro de coesão, você está fazendo join em dois datasets, por isso seria o resultado "nos datasets de notas" (plural) assim como na versão em inglês 52 - "em" duplicado 90 - Erro de tradução, "grades" se refere ao nome dos datasets de notas e não a "séries" 104 - Erro de digitação, a = à 114 - De onde saiu esse "Ou"? * Revisão técnica - Elias AVISO: Existem alguns comentários de discussão dos autores neste capítulo 35 - Erro de digitação, caraceter = caractere * Revisão técnica - Elias 15 - Erro de coesão, se "queremos dividir" então nós "damos comoo segundo argumento" e não "dá como segundo argumento" 39 - Adição de vírgula 42 - Título original estava em maiúsculo 44 - Adicionando acentuação 66 - Apagando resquicío do texto em inglês 68 - AVISO: "composíveis" é mesmo o termo apropriado aqui? Sintáticamente está correta mas nunca vi essa palavra escrita em nenhum lugar antes * Revisão Técnica - Henrique 3. O artigo de Wickham popularizou o split-apply-combine para a linguagem R, não A linguagem R. 4. Sugestão. 5. Sugestão. 15. Sugestão. 28. Sugestão. 39. Fazer um loop = iterar. 40. Sugestão. 68. Acho que o termo técnico aqui é função composta (mas não tenho certeza absoluta). * Update dataframes_indexing_pt.md * Update dataframes_indexing_pt.md * Update dataframes_performance_pt.md * Update dataframes_performance_pt.md * Update dataframes_performance_pt.md * Revisão técnica - Elias 1 - Título original está em maiúsculo 64 - Erro de coesão, ou "faz iteração pelo" ou "itera pelo", não "faz itera por" 82 - Se o título foi traduzido, esse subtítulo também não deveria ser? 99 - O termo técnico em português é "despacho múltiplo" 127 - Creio que esse "see" precisa ser traduzido 179 - Se o título foi traduzido, esse subtítulo também não deveria ser? 190 - Erro de digitação 191 - O termo técnico em português é "despacho múltiplo" 217 - O texto original menciona que você não descobriu o do "Zed" 241~250 - Não acho que era realmente necessário traduzir essa parte * Revisão técnica - Elias 9 - Melhor chamarmos de "exclamação" 12 - Erro de digitação vims = vimos 22 - "responses" é o nome do DataFrame 38 - Erro de digitação in loco = in-loco 81 - Melhor chamarmos de "exclamação" 86 - "responses" é o nome do DataFrame 123 - Algo parece estranho com o posicionamento da palavra sink 133 - Em português é chamado de pipe mesmo Co-authored-by: NMLebedev <[email protected]> Co-authored-by: Elias-Noda <[email protected]> Co-authored-by: Henrique Pougy <[email protected]> Co-authored-by: h-pgy <[email protected]>
1 parent b4c9ac1 commit 529d615

10 files changed

+1433
-19
lines changed

config.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@
4545
"preface_pt",
4646
"why_julia_pt",
4747
"julia_basics_pt",
48-
"dataframes",
49-
"dataframes_load_save",
50-
"dataframes_indexing",
51-
"dataframes_select",
52-
"dataframes_join",
53-
"dataframes_transform",
54-
"dataframes_groupby_combine",
55-
"dataframes_performance",
48+
"dataframes_pt",
49+
"dataframes_load_save_pt",
50+
"dataframes_indexing_pt",
51+
"dataframes_select_pt",
52+
"dataframes_join_pt",
53+
"dataframes_transform_pt",
54+
"dataframes_groupby_combine_pt",
55+
"dataframes_performance_pt",
5656
"data_vis_makie",
5757
"data_vis_makie_cairo",
5858
"data_vis_makie_attributes",
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
## Groupby e Combine {#sec:groupby_combine}
2+
3+
Para a linguagem de programação R, @wickham2011split popularizou a chamada estratégia _split-apply-combine (ou dividir-aplicar-combinar) para transformações de dados.
4+
Em essência, essa estratégia **divide** o dataset em grupos distintos, **aplica** uma ou mais funções para cada grupo e, depois, **combina** o resultado.
5+
`DataFrames.jl` suporta totalmente o método dividir-aplicar-combinar.
6+
Usaremos o exemplo das notas do aluno como antes.
7+
Suponha que queremos saber a nota média de cada aluno:
8+
9+
```jl
10+
@sco process=without_caption_label all_grades()
11+
```
12+
13+
A estratégia é **dividir** o dataset em alunos distintos, **aplicar** a função média para cada aluno e **combinar** o resultado.
14+
15+
A divisão é chamada `groupby` e passamos como segundo argumento o ID da coluna em que queremos dividir o dataset:
16+
17+
```jl
18+
s = "groupby(all_grades(), :name)"
19+
sco(s; process=string, post=plainblock)
20+
```
21+
22+
Nós aplicamos a função `mean` da biblioteca padrão de Julia no módulo `Statistics`:
23+
24+
```
25+
using Statistics
26+
```
27+
28+
Para aplicá-la, utilizamos a função `combine`:
29+
30+
```jl
31+
s = """
32+
gdf = groupby(all_grades(), :name)
33+
combine(gdf, :grade => mean)
34+
"""
35+
sco(s; process=without_caption_label)
36+
```
37+
38+
Imagine ter que fazer isso sem as funções `groupby` e `combine`.
39+
Precisaríamos iterar sobre nossos dados para dividi-los em grupos, em seguida, iterar sobre os registros em cada divisão para aplicar a função **e**, finalmente, iterar sobre cada grupo para obter o resultado final.
40+
Vê-se assim que é muito bom conhecer a técnica dividir-aplicar-combinar.
41+
42+
### Múltiplas Colunas de Origem {#sec:groupby_combine_multiple_source}
43+
44+
Mas, e se quisermos aplicar uma função à várias colunas de nosso dataset?
45+
46+
```jl
47+
s = """
48+
group = [:A, :A, :B, :B]
49+
X = 1:4
50+
Y = 5:8
51+
df = DataFrame(; group, X, Y)
52+
"""
53+
sco(s; process=without_caption_label)
54+
```
55+
56+
Isso é feito de maneira semelhante:
57+
58+
```jl
59+
s = """
60+
gdf = groupby(df, :group)
61+
combine(gdf, [:X, :Y] .=> mean; renamecols=false)
62+
"""
63+
sco(s; process=without_caption_label)
64+
```
65+
66+
Perceba que usamos o operador dot `.` antes da seta à direita `=>` para indicar que o `mean` tem que ser aplicado a múltiplas colunas de origem `[:X, :Y]`.
67+
68+
Para usar funções compostas, uma maneira simples é criar uma função que faça as transformações compostas pretendidas.
69+
Por exemplo, para uma série de valores, vamos primeiro pegar o `mean` seguido de `round` para um número inteiro (também conhecido como um inteiro `Int`):
70+
71+
```jl
72+
s = """
73+
gdf = groupby(df, :group)
74+
rounded_mean(data_col) = round(Int, mean(data_col))
75+
combine(gdf, [:X, :Y] .=> rounded_mean; renamecols=false)
76+
"""
77+
sco(s; process=without_caption_label)
78+
```

contents/dataframes_indexing_pt.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
## Indexação e Sumarização
2+
3+
Vamos voltar para o exemplo dos dados `grades_2020()` definidos antes:
4+
5+
```jl
6+
sco("grades_2020()"; process=without_caption_label)
7+
```
8+
9+
Para recuperar um **vetor** para `name`, podemos acessar o `DataFrame` com o `.`, como fizemos anteriormente com `struct`s em @sec:julia_basics:
10+
11+
```jl
12+
@sco JDS.names_grades1()
13+
```
14+
15+
ou podemos indexar um `DataFrame` de modo muito parecido com uma `Array` utilizando símbolos e caracteres especiais.
16+
O **segundo índice é a indexação da coluna**:
17+
18+
```jl
19+
@sco JDS.names_grades2()
20+
```
21+
22+
Perceba que `df.name` é exatamente o mesmo que o comando `df[!, :name]`, o que você pode verificar fazendo:
23+
24+
```
25+
julia> df = DataFrame(id=[1]);
26+
27+
julia> @edit df.name
28+
```
29+
30+
Em ambos os casos, ele dará a coluna `:name`.
31+
Também existe o comando `df[:, :name]` que copia a coluna `:name`.
32+
Na maioria dos casos, `df[!, :name]` é a melhor aposta, pois é mais versátil e faz uma modificação no local.
33+
34+
Para qualquer **linha**, digamos a segunda linha, podemos usar o **primeiro índice como indexação de linha**:
35+
36+
```jl
37+
s = """
38+
df = grades_2020()
39+
df[2, :]
40+
df = DataFrame(df[2, :]) # hide
41+
"""
42+
sco(s; process=without_caption_label)
43+
```
44+
45+
ou criar uma função para nos dar qualquer linha `i` que quisermos:
46+
47+
```jl
48+
@sco process=without_caption_label JDS.grade_2020(2)
49+
```
50+
51+
Podemos também obter apenas a coluna `names` para as 2 primeiras linhas usando **fatiamento** (novamente, de modo similar a um `Array`):
52+
53+
```jl
54+
@sco JDS.grades_indexing(grades_2020())
55+
```
56+
57+
Se assumirmos que todos os nomes na tabela são únicos, também podemos escrever uma função para obter a nota de uma pessoa por meio de seu `name`.
58+
Para fazer isso, convertemos a tabela de volta para uma das estruturas de dados básicas de Julia (veja @sec:data_structures) que é capaz de criar mapeamentos, a saber `Dict`s:
59+
60+
```jl
61+
@sco post=output_block grade_2020("Bob")
62+
```
63+
64+
que funciona porque `zip` itera pelo `df.name` e `df.grade_2020` ao mesmo tempo como um "zipper":
65+
66+
```jl
67+
sco("""
68+
df = grades_2020()
69+
collect(zip(df.name, df.grade_2020))
70+
""")
71+
```
72+
73+
Entretanto, converter um `DataFrame` para `Dict` só é útil quando os elementos são únicos.
74+
Geralmente esse não é o caso e é por isso que precisamos aprender como `filter` (filtrar) um `DataFrame`.
75+
76+
## Filtro e Subconjunto {#sec:filter_subset}
77+
78+
Existem duas maneiras de remover linhas de um `DataFrame`, uma é `filter` (@sec:filter) e outra é `subset` (@sec:subset).
79+
`filter` foi adicionado à biblioteca `DataFrames.jl` anteriormente, é mais poderoso e também tem uma sintaxe mais coerente em relação às bibliotecas básicas de Julia. É por isso que vamos iniciar essa seção discutindo `filter` primeiro.
80+
`subset` é mais recente e, comumente, é mais conveniente de usar.
81+
82+
### Filtro {#sec:filter}
83+
84+
A partir de agora, nós começaremos a adentrar funcionalidades mais robustas da biblioteca `DataFrames.jl`.
85+
Para fazer isso, precisaremos aprender sobre algumas funções, como `select` e `filter`.
86+
Mas não se preocupe!
87+
Pode ser um alívio saber que o **objetivo geral do design de `DataFrames.jl` é manter o número de funções que um usuário deve aprender em um mínimo[^verbos]**.
88+
89+
[^verbos]: De acordo com Bogumił Kamiński (desenvolvedor e mantenedor líder do `DataFrames.jl`) no Discourse (<https://discourse.julialang.org/t/pull-dataframes-columns-to-the-front/60327/5>).
90+
91+
Como antes, retomamos a partir de `grades_2020`:
92+
93+
```jl
94+
sco("grades_2020()"; process=without_caption_label)
95+
```
96+
97+
Podemos filtrar linhas usando `filter(source => f::Function, df)`.
98+
Perceba como essa função é similar à função `filter(f::Function, V::Vector)` do módulo `Base` de Julia.
99+
Isso ocorre porque `DataFrames.jl` usa **despacho múltiplo** (see @sec:multiple_dispatch) para definir um novo método de `filter` que aceita `DataFrame` como argumento.
100+
101+
À primeira vista, definir e trabalhar com uma função `f` para filtrar pode ser um pouco difícil de se usar na prática.
102+
Aguente firme, esse esforço é bem pago, uma vez que **é uma forma muito poderosa de filtrar dados**.
103+
Como um exemplo simples, podemos criar uma função `equals_alice` que verifica se sua entrada é igual "Alice":
104+
105+
```jl
106+
@sco post=output_block JDS.equals_alice("Bob")
107+
```
108+
109+
```jl
110+
sco("equals_alice(\"Alice\")"; post=output_block)
111+
```
112+
113+
Equipados com essa função, podemos usá-la como nossa função `f` para filtrar todas as linhas para as quais `name` equivale a "Alice":
114+
115+
```jl
116+
s = "filter(:name => equals_alice, grades_2020())"
117+
sco(s; process=without_caption_label)
118+
```
119+
120+
Observe que isso não funciona apenas para `DataFrame`, mas também para vetores:
121+
122+
```jl
123+
s = """filter(equals_alice, ["Alice", "Bob", "Dave"])"""
124+
sco(s)
125+
```
126+
127+
Podemos torná-lo um pouco menos prolixo usando uma **função anônima** (veja @sec:function_anonymous):
128+
129+
```jl
130+
s = """filter(n -> n == "Alice", ["Alice", "Bob", "Dave"])"""
131+
sco(s)
132+
```
133+
134+
que também podemos usar em `grades_2020`:
135+
136+
```jl
137+
s = """filter(:name => n -> n == "Alice", grades_2020())"""
138+
sco(s; process=without_caption_label)
139+
```
140+
141+
Recapitulando, esta chamada de função pode ser lida como "para cada elemento na linha `:name`, vamos chamar o elemento `n`, e checar se `n` se iguala a Alice".
142+
Para algumas pessoas, isso ainda é muito prolixo.
143+
Por sorte, Julia adicionou uma _aplicação de função parcial_ de `==`.
144+
Os detalhes não são importantes -- apenas saiba que você pode usá-la como qualquer outra função:
145+
146+
```jl
147+
sco("""
148+
s = "This is here to workaround a bug in books" # hide
149+
filter(:name => ==("Alice"), grades_2020())
150+
"""; process=without_caption_label)
151+
```
152+
153+
Para obter todas as linhas que *não* são Alice, `==` (igualdade) pode ser substituído por `!=` (desigualdade) em todos os exemplos anteriores:
154+
155+
```jl
156+
s = """filter(:name => !=("Alice"), grades_2020())"""
157+
sco(s; process=without_caption_label)
158+
```
159+
160+
Agora, para mostrar **porque funções anônimas são tão poderosas**, podemos criar um filtro um pouco mais complexo.
161+
Neste filtro, queremos as pessoas cujos nomes comecem com A ou B **e** tenham uma nota acima de 6:
162+
163+
```jl
164+
s = """
165+
function complex_filter(name, grade)::Bool
166+
interesting_name = startswith(name, 'A') || startswith(name, 'B')
167+
interesting_grade = 6 < grade
168+
interesting_name && interesting_grade
169+
end
170+
"""
171+
sc(s)
172+
```
173+
174+
```jl
175+
s = "filter([:name, :grade_2020] => complex_filter, grades_2020())"
176+
sco(s; process=without_caption_label)
177+
```
178+
179+
### Subconjunto {#sec:subset}
180+
181+
A função `subset` foi adicionada para tornar mais fácil trabalhar com valores ausentes (@sec:missing_data).
182+
Em contraste com `filter`, `subset` funciona em colunas completas ao invés de linhas ou valores únicos.
183+
Se quisermos usar nossas funções definidas anteriormente, devemos envolvê-las dentro de `ByRow`:
184+
185+
```jl
186+
s = "subset(grades_2020(), :name => ByRow(equals_alice))"
187+
sco(s; process=without_caption_label)
188+
```
189+
190+
Também perceba que `DataFrame` é agora o primeiro argumento `subset(df, args...)`, enquanto que em `filter` foi o segundo `filter(f, df)`.
191+
A razão para isso é que Julia define filtro como `filter(f, V::Vector)` e `DataFrames.jl` optou por manter a consistência com as funções Julia existentes que foram estendidas para tipos de `DataFrame`s de despacho múltiplo.
192+
193+
> **_OBSERVAÇÃO:_**
194+
> A maioria das funções nativas de `DataFrames.jl`, as quais `subset` pertence, tem uma **assinatura de função consistente que sempre recebe um `DataFrame` como primeiro argumento**.
195+
196+
Assim como com `filter`, também podemos usar funções anônimas dentro de `subset`:
197+
198+
```jl
199+
s = "subset(grades_2020(), :name => ByRow(name -> name == \"Alice\"))"
200+
sco(s; process=without_caption_label)
201+
```
202+
203+
Ou, a aplicação de função parcial para `==`:
204+
205+
```jl
206+
s = "subset(grades_2020(), :name => ByRow(==(\"Alice\")))"
207+
sco(s; process=without_caption_label)
208+
```
209+
210+
Em última análise, vamos mostrar o verdadeiro poder de `subset`.
211+
Primeiro, criamos um dataset com alguns valores ausentes:
212+
213+
```jl
214+
@sco salaries()
215+
```
216+
217+
Esses dados são sobre uma situação plausível em que você deseja descobrir os salários de seus colegas e ainda não descobriu o do Zed.
218+
Embora não queiramos incentivar essas práticas, suspeitamos que seja um exemplo interessante.
219+
Suponha que queremos saber quem ganha mais de 2.000.
220+
Se usarmos `filter`, sem levar em consideração os valores 'faltantes', ele falhará:
221+
222+
```jl
223+
s = "filter(:salary => >(2_000), salaries())"
224+
sce(s, post=trim_last_n_lines(25))
225+
```
226+
227+
`subset` também falhará, mas felizmente nos apontará para uma solução fácil:
228+
229+
```jl
230+
s = "subset(salaries(), :salary => ByRow(>(2_000)))"
231+
sce(s, post=trim_last_n_lines(25))
232+
```
233+
234+
Então, só precisamos passar o argumento de palavra-chave `skipmissing=true`:
235+
236+
```jl
237+
s = "subset(salaries(), :salary => ByRow(>(2_000)); skipmissing=true)"
238+
sco(s; process=without_caption_label)
239+
```
240+
241+
```{=comment}
242+
Rik, precisamos de um exemplo de filtro e subconjunto com várias condições, como em:
243+
244+
`filter(row -> row.col1 >= something1 && row.col2 <= something2, df)`
245+
246+
e:
247+
248+
`subset(df, :col1 => ByRow(>=(something1)), :col2 => ByRow(<=(something2)>))
249+
```

0 commit comments

Comments
 (0)