这是代码:
using DataFrames, DataFramesMeta
# Creating a sample DataFrame
df = DataFrame(ID = 1:5, Med1 = [0, 1, 0, 1, 0])
# Using @rsubset directly
result1 = @rsubset df :Med1 == 0
# Using a symbol
st = Symbol("Med1")
@rsubset df st == 0
# Checking if the results are the same
isequal(result1, result2)
结果是假的 - 为什么?
尝试了许多不同的组合,如果我不直接在表达式上定义符号,它永远不会起作用。我很感激关于使用 Dataframe 的列命名约定的最佳实践的一些建议(我有一堆数据集,其中的列标有“Med1”、“Med2”等数字......并且我想迭代这些数字,这就是我最终尝试创建符号的方式)
文档的简介部分接近结尾处有:
要引用 DataFramesMeta 宏中的列,请使用符号。例如,使用 :x 来引用列 df.x。要使用代表符号的变量 varname 来引用列,请使用语法 $varname。
因此(正如评论中提到的),您需要
$st
将 st
的值用作列名称。
其原因(据我了解)与 Julia 元编程的任何限制或内部工作原理无关,而是与惯例有关。
st == 0
看起来像是在将 st
的值与 0
进行比较,因此让它默默地比较名称包含在 st
中的 column将是意外且“神奇”的。当构建大型代码库时,这种魔法往往会降低代码的可读性和可维护性。使用
:
或 $
显式标记列访问可以更轻松地查看我们在何处引用列,以及在何处访问变量以获得其自身值。
(确实存在像 Tidier.jl 这样的包,为了方便起见,它们会更加神奇。例如,
@rsubset df :Med1 == 0
在 Tidier 中会写成 @filter df Med1 == 0
,名称“Med1”自动指代该列.这是一个例外,明确旨在遵循 R 的约定而不是 Julia 的约定。)
使列访问具有特殊语法还可以更轻松地访问代码中的普通变量,例如。
x, y = some_calculation()
@rsubset df $st == x + y
在这里,由于列访问具有特殊语法 (
$
),因此不会对 x
或 y
产生混淆 - 它们按预期引用普通变量 x
和 y
。
(相反,由于 Tidier 不需要特殊的列名语法,所以它采用了相反的方式,并且 有特殊的语法 用于引用普通变量,例如。
@filter df Med1 == !!x + !!y
。)
所以最终,这是 DataFramesMeta 开发人员的设计决策,而不是 Julia 元编程固有的东西。