英文:
How to check if a variable is available in the data else use a value provided by user in a R custom function?
问题
我编写了一个自定义函数,其中的数据参数如下所示:
``` R
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
Sepal.Length = data[[Sepal.Length]]
Sepal.Width = data[[Sepal.Width]]
Petal.Width = data[[Petal.Width]]
Petal.Length = data[[Petal.Length]]
#计算一些派生参数
deltak <- (Sepal.Length - Sepal.Width)/390
ARk <- Petal.Width*2
dat <- cbind.data.frame(deltak, ARk)
#拟合二次模型
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
}
如果所有变量都在数据框中可用,它能够正常工作,如下所示:
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)
现在,如果我想要为 Petal.Length
使用一个数值,比如:
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = 55, data = iris)
它会返回以下错误:
>Error in .subset2(x, i, exact = exact) : subscript out of bounds
实际上,我想要有一个选项,即如果数据中存在 Petal.Length
,则应该使用先前的函数,否则将使用 Petal.Length
的值。我该如何做呢?
<details>
<summary>英文:</summary>
I have written a custom function with data aurgument like
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
Sepal.Length = data[[Sepal.Length]]
Sepal.Width = data[[Sepal.Width]]
Petal.Width = data[[Petal.Width]]
Petal.Length = data[[Petal.Length]]
#Calculate some derived parameters
deltak <- (Sepal.Length - Sepal.Width)/390
ARk <- Petal.Width*2
dat <- cbind.data.frame(deltak, ARk)
#Fitting quadratic model
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(list(DeltaK0
= deltaK0, Ks
= Ks))
}
It is working fine if all the variables are available in the data frame like
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)
Now, if I want to use one numeric value for `Petal.Length` like
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = 55, data = iris)
It returns the following error
>Error in .subset2(x, i, exact = exact) : subscript out of bounds
Actually, I want to have an option like if the `Petal.Length` is available in the data, then the earlier function should work, else it will utilise the value of `Petal.Length`. How can I do that?
</details>
# 答案1
**得分**: 3
如果我们要检查所有参数
```R
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
# 获取参数的名称并返回其值
tmpLst <- mget(names(formals()))
# 从列表中删除'data'组件
tmpLst <- tmpLst[setdiff(names(tmpLst), "data")]
# 通过unlisting创建一个向量
tmpVec <- unlist(tmpLst)
# 通过检查它们是否作为数据的列而创建一个逻辑索引
indx <- tmpVec %in% names(data)
if (any(!indx)) # 如果有任何不在的
{
# 使用相应列表的值更新数据的列
data[names(tmpVec)[!indx]] <- tmpLst[!indx]
}
# 从这里开始使用OP的函数...
Sepal.Length <- data[["Sepal.Length"]]
Sepal.Width <- data[["Sepal.Width"]]
Petal.Width <- data[["Petal.Width"]]
Petal.Length <- data[["Petal.Length"]]
# 计算一些派生参数
deltak <- (Sepal.Length - Sepal.Width)/390
ARk <- Petal.Width*2
dat <- cbind.data.frame(deltak, ARk)
# 拟合二次模型
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
}
- 测试
> Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
+ Petal.Width = "Petal.Width", Petal.Length = 55, data = iris)
$DeltaK0
[1] 0.002795248
$Ks
...
> Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
+ Petal.Width = 25, Petal.Length = "Petal.Length", data = iris)
$DeltaK0
[1] 0.00714359
$Ks
[1] 1.3928564 1.3928564 1.2928564 1.4928564 1.3928564 1.6928564 ..
> Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
+ Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)
$DeltaK0
[1] 0.002795248
$Ks
[1] 1.3972048 1.3972048 1.2972048 1.4972048 1.3972048 1.6972048 ...
请注意,我已经忽略了代码部分,只翻译了您提供的R函数和测试部分。
英文:
If we are checking for all arguments
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
# get the names of the arguments and return its value with mget
tmpLst <- mget(names(formals()))
# subset the list without the 'data' component
tmpLst <- tmpLst[setdiff(names(tmpLst), "data")]
# create a vector by unlisting
tmpVec <- unlist(tmpLst)
# create a logical index by checking whether those are present as
# columns in the data
indx <- tmpVec %in% names(data)
if(any(!indx)) # if there are any not present
{
# update the columns of data with the value of the corresponding list
data[names(tmpVec)[!indx]] <- tmpLst[!indx]
}
# using OP's function from here on...
Sepal.Length <- data[["Sepal.Length"]]
Sepal.Width <- data[["Sepal.Width"]]
Petal.Width <- data[["Petal.Width"]]
Petal.Length <- data[["Petal.Length"]]
#Calculate some derived parameters
deltak <- (Sepal.Length - Sepal.Width)/390
ARk <- Petal.Width*2
dat <- cbind.data.frame(deltak, ARk)
#Fitting quadratic model
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
}
-testing
> Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
+ Petal.Width = "Petal.Width", Petal.Length = 55, data = iris)
$DeltaK0
[1] 0.002795248
$Ks
...
> Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
+ Petal.Width = 25, Petal.Length = "Petal.Length", data = iris)
$DeltaK0
[1] 0.00714359
$Ks
[1] 1.3928564 1.3928564 1.2928564 1.4928564 1.3928564 1.6928564 ..
...
> > Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
+ Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)
$DeltaK0
[1] 0.002795248
$Ks
[1] 1.3972048 1.3972048 1.2972048 1.4972048 1.3972048 1.6972048 1.3972048 1.4972048 1.3972048 1.4972048 1.4972048 1.5972048 1.3972048 1.0972048
[15] 1.1972048 1.4972048 1.2972048 1.3972048 1.6972048 1.4972048 1.6972048 1.4972048 0.9972048 1.6972048 1.8972048 1.5972048 1.5972048 1.4972048
[29] 1.3972048 1.5972048 1.5972048 1.4972048 1.4972048 1.3972048 1.497 ...
答案2
得分: 2
一种方法是检查 Petal.Length
参数是否是数值或列名。
如果是数值,则直接赋给 Petal.Length
。
如果是列名,则使用提供的值。
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length") {
Sepal.Length <- data[[Sepal.Length]]
Sepal.Width <- data[[Sepal.Width]]
Petal.Width <- data[[Petal.Width]]
if (is.numeric(Petal.Length)) {
# 直接使用提供的数值
Petal.Length <- rep(Petal.Length, nrow(data))
} else if (is.character(Petal.Length)) {
# 根据列名提取列的值
Petal.Length <- data[[Petal.Length]]
} else {
stop("Petal.Length 参数无效。")
}
# 计算一些派生参数
deltak <- (Sepal.Length - Sepal.Width) / 390
ARk <- Petal.Width * 2
dat <- cbind.data.frame(deltak, ARk)
# 拟合二次模型
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
}
# 使用列名
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length",
data = iris)
# 使用数值
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = 55,
data = iris)
希望这有帮助。
英文:
One way is to check if the Petal.Length
argument is a numeric value or a column name.
If numeric value then assign directly to Petal.Length
.
If a column name then use the provided value.
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length") {
Sepal.Length <- data[[Sepal.Length]]
Sepal.Width <- data[[Sepal.Width]]
Petal.Width <- data[[Petal.Width]]
if (is.numeric(Petal.Length)) {
# Use the provided numeric value directly
Petal.Length <- rep(Petal.Length, nrow(data))
} else if (is.character(Petal.Length)) {
# Extract the column values based on the column name
Petal.Length <- data[[Petal.Length]]
} else {
stop("Invalid argument for Petal.Length.")
}
# Calculate some derived parameters
deltak <- (Sepal.Length - Sepal.Width) / 390
ARk <- Petal.Width * 2
dat <- cbind.data.frame(deltak, ARk)
# Fitting quadratic model
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
}
# Using a column name
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length",
data = iris)
# Using a numeric value
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = 55,
data = iris)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论