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评论97阅读模式
英文:

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

问题

  1. 我编写了一个自定义函数,其中的数据参数如下所示:
  2. ``` R
  3. Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  4. Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
  5. Sepal.Length = data[[Sepal.Length]]
  6. Sepal.Width = data[[Sepal.Width]]
  7. Petal.Width = data[[Petal.Width]]
  8. Petal.Length = data[[Petal.Length]]
  9. #计算一些派生参数
  10. deltak <- (Sepal.Length - Sepal.Width)/390
  11. ARk <- Petal.Width*2
  12. dat <- cbind.data.frame(deltak, ARk)
  13. #拟合二次模型
  14. mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  15. deltaK0 <- abs(mod$coefficients[[1]])
  16. Ks <- Petal.Length - deltaK0
  17. return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
  18. }

如果所有变量都在数据框中可用,它能够正常工作,如下所示:

  1. Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  2. Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)

现在,如果我想要为 Petal.Length 使用一个数值,比如:

  1. Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  2. Petal.Width = "Petal.Width", Petal.Length = 55, data = iris)

它会返回以下错误:
>Error in .subset2(x, i, exact = exact) : subscript out of bounds

实际上,我想要有一个选项,即如果数据中存在 Petal.Length,则应该使用先前的函数,否则将使用 Petal.Length 的值。我该如何做呢?

  1. <details>
  2. <summary>英文:</summary>
  3. 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))
}

  1. 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)

  1. 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)

  1. It returns the following error
  2. &gt;Error in .subset2(x, i, exact = exact) : subscript out of bounds
  3. 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?
  4. </details>
  5. # 答案1
  6. **得分**: 3
  7. 如果我们要检查所有参数
  8. ```R
  9. Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  10. Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
  11. # 获取参数的名称并返回其值
  12. tmpLst <- mget(names(formals()))
  13. # 从列表中删除'data'组件
  14. tmpLst <- tmpLst[setdiff(names(tmpLst), "data")]
  15. # 通过unlisting创建一个向量
  16. tmpVec <- unlist(tmpLst)
  17. # 通过检查它们是否作为数据的列而创建一个逻辑索引
  18. indx <- tmpVec %in% names(data)
  19. if (any(!indx)) # 如果有任何不在的
  20. {
  21. # 使用相应列表的值更新数据的列
  22. data[names(tmpVec)[!indx]] <- tmpLst[!indx]
  23. }
  24. # 从这里开始使用OP的函数...
  25. Sepal.Length <- data[["Sepal.Length"]]
  26. Sepal.Width <- data[["Sepal.Width"]]
  27. Petal.Width <- data[["Petal.Width"]]
  28. Petal.Length <- data[["Petal.Length"]]
  29. # 计算一些派生参数
  30. deltak <- (Sepal.Length - Sepal.Width)/390
  31. ARk <- Petal.Width*2
  32. dat <- cbind.data.frame(deltak, ARk)
  33. # 拟合二次模型
  34. mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  35. deltaK0 <- abs(mod$coefficients[[1]])
  36. Ks <- Petal.Length - deltaK0
  37. return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
  38. }
  • 测试
  1. > Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  2. + Petal.Width = "Petal.Width", Petal.Length = 55, data = iris)
  3. $DeltaK0
  4. [1] 0.002795248
  5. $Ks
  6. ...
  7. > Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  8. + Petal.Width = 25, Petal.Length = "Petal.Length", data = iris)
  9. $DeltaK0
  10. [1] 0.00714359
  11. $Ks
  12. [1] 1.3928564 1.3928564 1.2928564 1.4928564 1.3928564 1.6928564 ..
  13. > Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  14. + Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)
  15. $DeltaK0
  16. [1] 0.002795248
  17. $Ks
  18. [1] 1.3972048 1.3972048 1.2972048 1.4972048 1.3972048 1.6972048 ...

请注意,我已经忽略了代码部分,只翻译了您提供的R函数和测试部分。

英文:

If we are checking for all arguments

  1. Ploy &lt;- function(data, Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  2. Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;){
  3. # get the names of the arguments and return its value with mget
  4. tmpLst &lt;- mget(names(formals()))
  5. # subset the list without the &#39;data&#39; component
  6. tmpLst &lt;- tmpLst[setdiff(names(tmpLst), &quot;data&quot;)]
  7. # create a vector by unlisting
  8. tmpVec &lt;- unlist(tmpLst)
  9. # create a logical index by checking whether those are present as
  10. # columns in the data
  11. indx &lt;- tmpVec %in% names(data)
  12. if(any(!indx)) # if there are any not present
  13. {
  14. # update the columns of data with the value of the corresponding list
  15. data[names(tmpVec)[!indx]] &lt;- tmpLst[!indx]
  16. }
  17. # using OP&#39;s function from here on...
  18. Sepal.Length &lt;- data[[&quot;Sepal.Length&quot;]]
  19. Sepal.Width &lt;- data[[&quot;Sepal.Width&quot;]]
  20. Petal.Width &lt;- data[[&quot;Petal.Width&quot;]]
  21. Petal.Length &lt;- data[[&quot;Petal.Length&quot;]]
  22. #Calculate some derived parameters
  23. deltak &lt;- (Sepal.Length - Sepal.Width)/390
  24. ARk &lt;- Petal.Width*2
  25. dat &lt;- cbind.data.frame(deltak, ARk)
  26. #Fitting quadratic model
  27. mod &lt;- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  28. deltaK0 &lt;- abs(mod$coefficients[[1]])
  29. Ks &lt;- Petal.Length - deltaK0
  30. return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
  31. }

-testing

  1. &gt; Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  2. + Petal.Width = &quot;Petal.Width&quot;, Petal.Length = 55, data = iris)
  3. $DeltaK0
  4. [1] 0.002795248
  5. $Ks
  6. ...
  7. &gt; Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  8. + Petal.Width = 25, Petal.Length = &quot;Petal.Length&quot;, data = iris)
  9. $DeltaK0
  10. [1] 0.00714359
  11. $Ks
  12. [1] 1.3928564 1.3928564 1.2928564 1.4928564 1.3928564 1.6928564 ..
  13. ...
  14. &gt; &gt; Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  15. + Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;, data = iris)
  16. $DeltaK0
  17. [1] 0.002795248
  18. $Ks
  19. [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
  20. [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
  21. [29] 1.3972048 1.5972048 1.5972048 1.4972048 1.4972048 1.3972048 1.497 ...

答案2

得分: 2

一种方法是检查 Petal.Length 参数是否是数值或列名。

如果是数值,则直接赋给 Petal.Length

如果是列名,则使用提供的值。

  1. Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  2. Petal.Width = "Petal.Width", Petal.Length = "Petal.Length") {
  3. Sepal.Length <- data[[Sepal.Length]]
  4. Sepal.Width <- data[[Sepal.Width]]
  5. Petal.Width <- data[[Petal.Width]]
  6. if (is.numeric(Petal.Length)) {
  7. # 直接使用提供的数值
  8. Petal.Length <- rep(Petal.Length, nrow(data))
  9. } else if (is.character(Petal.Length)) {
  10. # 根据列名提取列的值
  11. Petal.Length <- data[[Petal.Length]]
  12. } else {
  13. stop("Petal.Length 参数无效。")
  14. }
  15. # 计算一些派生参数
  16. deltak <- (Sepal.Length - Sepal.Width) / 390
  17. ARk <- Petal.Width * 2
  18. dat <- cbind.data.frame(deltak, ARk)
  19. # 拟合二次模型
  20. mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  21. deltaK0 <- abs(mod$coefficients[[1]])
  22. Ks <- Petal.Length - deltaK0
  23. return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
  24. }
  25. # 使用列名
  26. Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  27. Petal.Width = "Petal.Width", Petal.Length = "Petal.Length",
  28. data = iris)
  29. # 使用数值
  30. Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
  31. Petal.Width = "Petal.Width", Petal.Length = 55,
  32. 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.

  1. Ploy &lt;- function(data, Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  2. Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;) {
  3. Sepal.Length &lt;- data[[Sepal.Length]]
  4. Sepal.Width &lt;- data[[Sepal.Width]]
  5. Petal.Width &lt;- data[[Petal.Width]]
  6. if (is.numeric(Petal.Length)) {
  7. # Use the provided numeric value directly
  8. Petal.Length &lt;- rep(Petal.Length, nrow(data))
  9. } else if (is.character(Petal.Length)) {
  10. # Extract the column values based on the column name
  11. Petal.Length &lt;- data[[Petal.Length]]
  12. } else {
  13. stop(&quot;Invalid argument for Petal.Length.&quot;)
  14. }
  15. # Calculate some derived parameters
  16. deltak &lt;- (Sepal.Length - Sepal.Width) / 390
  17. ARk &lt;- Petal.Width * 2
  18. dat &lt;- cbind.data.frame(deltak, ARk)
  19. # Fitting quadratic model
  20. mod &lt;- lm(deltak ~ poly(ARk, 2, raw = TRUE))
  21. deltaK0 &lt;- abs(mod$coefficients[[1]])
  22. Ks &lt;- Petal.Length - deltaK0
  23. return(list(`DeltaK0` = deltaK0, `Ks` = Ks))
  24. }
  25. # Using a column name
  26. Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  27. Petal.Width = &quot;Petal.Width&quot;, Petal.Length = &quot;Petal.Length&quot;,
  28. data = iris)
  29. # Using a numeric value
  30. Ploy(Sepal.Length = &quot;Sepal.Length&quot;, Sepal.Width = &quot;Sepal.Width&quot;,
  31. Petal.Width = &quot;Petal.Width&quot;, Petal.Length = 55,
  32. 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:

确定