How to check if a variable is available in the data else use a value provided by user in a R custom function?

huangapple go评论72阅读模式
英文:

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
&gt;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 &lt;- function(data, Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
                   Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;){
  
   # get the names of the arguments and return its value with mget
   tmpLst &lt;- mget(names(formals()))
   # subset the list without the &#39;data&#39; component
   tmpLst &lt;- tmpLst[setdiff(names(tmpLst), &quot;data&quot;)]
   # create a vector by unlisting
   tmpVec &lt;- unlist(tmpLst)
  # create a logical index by checking whether those are present as
  # columns in the data
  indx &lt;- 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]] &lt;- tmpLst[!indx]
   }
  
  # using OP&#39;s function from here on...
  Sepal.Length &lt;- data[[&quot;Sepal.Length&quot;]]
  Sepal.Width &lt;- data[[&quot;Sepal.Width&quot;]]
  Petal.Width &lt;- data[[&quot;Petal.Width&quot;]]
  Petal.Length &lt;- data[[&quot;Petal.Length&quot;]]

  #Calculate some derived parameters
  deltak &lt;- (Sepal.Length - Sepal.Width)/390
  ARk &lt;- Petal.Width*2
  
  dat &lt;- cbind.data.frame(deltak, ARk)
  
  #Fitting quadratic model
  mod &lt;- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  
  deltaK0 &lt;- abs(mod$coefficients[[1]])
  
  Ks &lt;- Petal.Length - deltaK0
  
  return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
  
  
  
   
   
  }

-testing

&gt; Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
+        Petal.Width = &quot;Petal.Width&quot;, Petal.Length = 55, data = iris)
$DeltaK0
[1] 0.002795248

$Ks
 ...

&gt; Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
+         Petal.Width = 25, Petal.Length = &quot;Petal.Length&quot;, data = iris)
$DeltaK0
[1] 0.00714359

$Ks
  [1] 1.3928564 1.3928564 1.2928564 1.4928564 1.3928564 1.6928564 ..
...

&gt; &gt; Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
+       Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;, 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 &lt;- function(data, Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
                 Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;) {
  
  Sepal.Length &lt;- data[[Sepal.Length]]
  Sepal.Width &lt;- data[[Sepal.Width]]
  Petal.Width &lt;- data[[Petal.Width]]
  
  if (is.numeric(Petal.Length)) {
    # Use the provided numeric value directly
    Petal.Length &lt;- rep(Petal.Length, nrow(data))
  } else if (is.character(Petal.Length)) {
    # Extract the column values based on the column name
    Petal.Length &lt;- data[[Petal.Length]]
  } else {
    stop(&quot;Invalid argument for Petal.Length.&quot;)
  }
  
  # Calculate some derived parameters
  deltak &lt;- (Sepal.Length - Sepal.Width) / 390
  ARk &lt;- Petal.Width * 2
  
  dat &lt;- cbind.data.frame(deltak, ARk)
  
  # Fitting quadratic model
  mod &lt;- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  
  deltaK0 &lt;- abs(mod$coefficients[[1]])
  
  Ks &lt;- Petal.Length - deltaK0
  
  return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
}

# Using a column name
Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
                Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;, 
                data = iris)

# Using a numeric value
Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;, 
                Petal.Width = &quot;Petal.Width&quot;, Petal.Length = 55, 
                data = iris)

huangapple
  • 本文由 发表于 2023年5月28日 13:28:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350081.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定