在 Section 4.4 中, 我们使用 select 函数选择一列或多列源数据, 并传入一个或多个目标列 source => target。 同样也有例子帮助回忆: select(df, :name => :people_names)

    本节将讨论如何 变换 变量,即如何 更改数据DataFrames.jl 中对应的语法是 source => transformation => target

    与之前一样,使用 grades_2020 数据集:

    假设想要 grades_2020 中的所有成绩加 1。 首先,需要定义一个接收向量数据并使所有元素加 1 的函数。 然后使用 DataFrames.jl 中的 transform 函数。与其他原生 DataFrames.jl 函数一样,按照其语法,它接收 DataFrame 作为第一个参数:

    1. transform(grades_2020(), :grade_2020 => plus_one)
    namegrade_2020grade_2020_plus_one
    Sally1.02.0
    Bob5.06.0
    Alice8.59.5
    Hank4.05.0

    如之前所说, DataFrames.jl 总是支持 source => transformation => target 这样的短语法。 所以,如果想在输出中保留 target 列的命名,操作如下:

    1. transform(grades_2020(), :grade_2020 => plus_one => :grade_2020)

    也可以使用关键字参数 renamecols=false

    namegrade_2020
    Sally2.0
    Bob6.0
    Alice9.5
    Hank5.0

    还可以使用 select 实现相同的转换,具体如下:

    1. select(grades_2020(), :, :grade_2020 => plus_one => :grade_2020)

    其中 : 表明 “选择所有列” ,正如在 Section 讨论的那样。 另外,还可以使用 Julia 广播更改 grade_2020 列,即直接访问 :

    1. df.grade_2020 = plus_one.(df.grade_2020)
    2. df
    namegrade_2020
    Sally2.0
    Bob6.0
    Alice9.5
    Hank5.0

    为了展示如何同时更改两列, 我们使用 Section 中的左合并数据:

    结合此数据集,我们增加一列来判断每位同学是否都有一门课的成绩大于 5.5:

    1. pass(A, B) = [5.5 < a || 5.5 < b for (a, b) in zip(A, B)]
    2. transform(leftjoined, [:grade_2020, :grade_2021] => pass; renamecols=false)
    namegrade_2020grade_2021grade_2020_grade_2021
    Sally1.09.5true
    Hank4.06.0true
    Bob5.0missingmissing
    Alice8.5missingtrue

    可以清理下结果,并将上述逻辑整合到一个函数中,然后最终得到符合标准学生的名单:

    1. function only_pass()
    2. pass(A, B) = [5.5 < a || 5.5 < b for (a, b) in zip(A, B)]
    3. leftjoined = transform(leftjoined, [:grade_2020, :grade_2021] => pass => :pass)
    4. passed = subset(leftjoined, :pass; skipmissing=true)
    5. return passed.name
    6. end