在 R 中为动态执行的函数设置一个值
Setting a value to a dynamically executed function in R
对于实验室数据,测量结果通常带有 detection/reporting 限制和置信区间。例如,我可能测量水中的镁浓度,其中最小报告值为 5,并且我收到了两次测量,第一次是 10,第二次是“<5”(即低于报告值)。作为最终用户,有时您希望将“<5”视为“5”,有时将其视为“0”,有时将其视为“2.5”。
我是如何解决这个问题的,方法是构建一个带有属性 LRL(报告下限)的 S3 class。我希望能够让用户执行以下操作:
a <- set_measurement("<5", LRL = 5)
b <- set_measurement(8, LRL = 5)
set_conservatism(1) # sets a global variable called "conservatism_coefficient" to 1
a
# 5 [LRL: 5]
c <- b + a
# 13 [LRL: 5]
set_conservatism(0.5)
a
# 2.5 [LRL: 5]
b + a
# 10.5 [LRL: 5]
c
# 13 [LRL: 5]
我想象的是 "a' is somehow set to "LRL*conservatism_co-efficient" 的值而不是数字。然后当其他一些函数尝试访问该值时,该值是基于动态计算的当前 conservatism_co-efficient.
这可能吗,and/or我是不是完全用错了方法?
不要害怕尝试重载您需要的通用函数。您只需修改 print
函数和算术运算组 Ops
:
即可实现您想要的效果
set_conservatism = function(factor) {
# Set global CONSERVATISM
CONSERVATISM <<- factor
}
set_measurement = function(value, lrl=5) {
# Create a new measurement
v_ = "measurement" # Dummy identifier
# Set attributes of a measurement
measurement = structure(v_, "value"=value, "lrl"=lrl)
# Set class attribute of measurement
class(measurement) = "measurement"
measurement
}
update_measurement = function(x) {
# Return value of measurement based on CONSERVATISM
if (attr(x, "value") < attr(x, "lrl")) {
attr(x, "lrl") * CONSERVATISM
} else {
attr(x, "value")
}
}
print.measurement = function(x, ...) {
# UserMethod for printing a measurement
update_measurement(x)
}
Ops.measurement = function(e1, e2) {
# UserMethod for arithmetic operations with measurements
e1 = update_measurement(e1)
e2 = update_measurement(e2)
NextMethod(.Generic)
}
a = set_measurement(0) # Any value smaller than lrl will do
b = set_measurement(8)
set_conservatism(1)
a + b
>>> 13
set_conservatism(0.5)
a + b
>>> 10.5
(来自 Python 程序员的旁注:使用 Python 中的 属性 并通过覆盖魔术方法可以很容易地实现这样的事情)
对于实验室数据,测量结果通常带有 detection/reporting 限制和置信区间。例如,我可能测量水中的镁浓度,其中最小报告值为 5,并且我收到了两次测量,第一次是 10,第二次是“<5”(即低于报告值)。作为最终用户,有时您希望将“<5”视为“5”,有时将其视为“0”,有时将其视为“2.5”。
我是如何解决这个问题的,方法是构建一个带有属性 LRL(报告下限)的 S3 class。我希望能够让用户执行以下操作:
a <- set_measurement("<5", LRL = 5)
b <- set_measurement(8, LRL = 5)
set_conservatism(1) # sets a global variable called "conservatism_coefficient" to 1
a
# 5 [LRL: 5]
c <- b + a
# 13 [LRL: 5]
set_conservatism(0.5)
a
# 2.5 [LRL: 5]
b + a
# 10.5 [LRL: 5]
c
# 13 [LRL: 5]
我想象的是 "a' is somehow set to "LRL*conservatism_co-efficient" 的值而不是数字。然后当其他一些函数尝试访问该值时,该值是基于动态计算的当前 conservatism_co-efficient.
这可能吗,and/or我是不是完全用错了方法?
不要害怕尝试重载您需要的通用函数。您只需修改 print
函数和算术运算组 Ops
:
set_conservatism = function(factor) {
# Set global CONSERVATISM
CONSERVATISM <<- factor
}
set_measurement = function(value, lrl=5) {
# Create a new measurement
v_ = "measurement" # Dummy identifier
# Set attributes of a measurement
measurement = structure(v_, "value"=value, "lrl"=lrl)
# Set class attribute of measurement
class(measurement) = "measurement"
measurement
}
update_measurement = function(x) {
# Return value of measurement based on CONSERVATISM
if (attr(x, "value") < attr(x, "lrl")) {
attr(x, "lrl") * CONSERVATISM
} else {
attr(x, "value")
}
}
print.measurement = function(x, ...) {
# UserMethod for printing a measurement
update_measurement(x)
}
Ops.measurement = function(e1, e2) {
# UserMethod for arithmetic operations with measurements
e1 = update_measurement(e1)
e2 = update_measurement(e2)
NextMethod(.Generic)
}
a = set_measurement(0) # Any value smaller than lrl will do
b = set_measurement(8)
set_conservatism(1)
a + b
>>> 13
set_conservatism(0.5)
a + b
>>> 10.5
(来自 Python 程序员的旁注:使用 Python 中的 属性 并通过覆盖魔术方法可以很容易地实现这样的事情)