如何在数据框中的同一列中为每一行执行不同的操作。

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

How to perfom different operations for every row in one same column in a data frame

问题

Here's the corrected R function to calculate the volume for different shapes based on your requirements:

  1. Biovol3 <- function(data_frame) {
  2. # Create a vector of shape names
  3. shapes <- unique(data_frame$Shape)
  4. # Initialize an empty vector for volumes
  5. volumes <- numeric(length(shapes))
  6. # Loop through each shape
  7. for (i in 1:length(shapes)) {
  8. shape_name <- shapes[i]
  9. shape_data <- data_frame[data_frame$Shape == shape_name, ]
  10. if (shape_name == "Ellipsoid") {
  11. # Calculate the volume using equation 1
  12. vol <- (pi/6) * shape_data$Dim_a * shape_data$Dim_b * shape_data$Dim_c
  13. } else if (shape_name == "Rectangular_box") {
  14. # Calculate the volume using equation 2
  15. vol <- shape_data$Dim_a * shape_data$Dim_b * shape_data$Dim_c
  16. } else {
  17. # Handle other shapes here if needed
  18. vol <- NA
  19. }
  20. # Store the volumes in the corresponding position
  21. volumes[i] <- vol
  22. }
  23. # Add the volumes as a new column in the original data frame
  24. data_frame$vol <- volumes
  25. return(data_frame)
  26. }
  27. # Example usage:
  28. # result_data_frame <- Biovol3(your_data_frame)

This modified function calculates the volume for each shape separately using the appropriate equation and stores the results in the volumes vector. Then, it adds the volume values as a new column in the original data frame.

You can use this function with your data frame to get the desired results.

英文:

I would like to create an R function in which, the input data will be a data frame with the following structure:

Shape Dim_a Dim_b Dim_c
Ellipsoid 23 10 23
Rectangular_box 4 65 18

And, for each different shape (i.e, 'Ellipsoid', 'Rectangular_box'), I would like to use a differente equation to calculate the volume using the respective value of the dimenstions (i.e, 'Dim_a', 'Dim_b', 'Dim_c').

For example, for 'Ellipsoid' shape, the equation to calculate the volume is:

vol = (pi/6) * Dim_a * Dim_b * Dim_c (eq. 1)

And for 'Rectangular_box', the equation is:

vol = Dim_a * Dim_b * Dim_c (eq. 2)

So, in my R function I would like to do "if Ellipsoid shape, then use eq. 1, but if Rectangular shape, then use eq. 2".

And the output is a new column with the results of calculate the volume for each different shape.

I was trying to do this:

  1. Biovol3 &lt;- function(data_frame){ #The input is a data frame
  2. # The variables are: &#39;Shape&#39; and the different dimentions &#39;Dim_a&#39;, &#39;Dim_b&#39;, &#39;Dim_c&#39; that must be included in the data frame
  3. Shape &lt;- data_frame$Shape
  4. Dim_a &lt;- data_frame$Dim_a
  5. Dim_b &lt;- data_frame$Dim_b
  6. Dim_c &lt;- data_frame$Dim_c
  7. # Then I tried to use &#39;which&#39; function to select the shape
  8. common_sp &lt;- c(&quot;Ellipsoid&quot;, &quot;Rectangular_box&quot;) # common shapes that must be included in the &#39;shape&#39; column in the data frame
  9. sel_sp &lt;- which(common_sp == Shape)
  10. # Using &#39;if&#39; statement to calculate the volume for each different shape
  11. if(any(sel_sp == 1)){
  12. vol = (pi/6) * Dim_a * Dim_b * Dim_c
  13. }
  14. if(any(sel_sp == 2)){
  15. vol = Dim_a * Dim_b * Dim_c
  16. }
  17. # The output must be a data frame with a new column &#39;volume&#39;
  18. result_data_frame &lt;- data.frame(data_frame,
  19. vol = unname(vol),
  20. Area = unname(Area))
  21. return(result_data_frame)
  22. }

This returns me the following data frame as a result:

Shape Dim_a Dim_b Dim_c vol
Ellipsoid 23 10 23 5290
Rectangular_box 4 65 18 4680

But the result of volume of Ellipsoid is incorrect. I notice that this is because the function only use one of the equations (in this case, the eq. 2), in both shapes, I don't know how to use the different equations corresponding to the different shapes.

答案1

得分: 1

在基础R中,你可以这样做:

  1. frac <- c(Ellipsoid = pi/6, Rectangular_box = 1)
  2. df$vol <- frac[df$Shape] * df$Dim_a * df$Dim_b * df$Dim_c
  3. df
  4. Shape Dim_a Dim_b Dim_c vol
  5. 1 Ellipsoid 23 10 23 2769.838
  6. 2 Rectangular_box 4 65 18 4680.000
英文:

in Base R you could do:

  1. frac &lt;- c(Ellipsoid = pi/6, Rectangular_box = 1)
  2. df$vol &lt;- frac[df$Shape] * df$Dim_a * df$Dim_b * df$Dim_c
  3. df
  4. Shape Dim_a Dim_b Dim_c vol
  5. 1 Ellipsoid 23 10 23 2769.838
  6. 2 Rectangular_box 4 65 18 4680.000

答案2

得分: 0

您可以使用 mutateifelse

  1. df %&gt;% mutate (
  2. vol = ifelse(df$Shape %in% &#39;Ellipsoid&#39;,
  3. (pi/6) * Dim_a * Dim_b * Dim_c),
  4. Dim_a * Dim_b * Dim_c
  5. )
英文:

You could use mutate and ifelse

  1. df %&gt;% mutate (
  2. vol = ifelse(df$Shape %in% &#39;Ellipsoid&#39;,
  3. (pi/6) * Dim_a * Dim_b * Dim_c),
  4. Dim_a * Dim_b * Dim_c
  5. )

答案3

得分: 0

以下是翻译好的代码部分:

  1. 虚拟数据:
  2. library(tidyverse)
  3. df1 <- tribble(~Shape, ~Dim_a, ~Dim_b, ~Dim_c,
  4. "椭球体", 23, 10, 23,
  5. "矩形盒", 4, 65, 18)
  6. 您可以使用与"shape"相同的名称创建一个函数列表:
  7. fun_list <- list(椭球体 = function(Dim_a, Dim_b, Dim_c) {(pi/6) * Dim_a * Dim_b * Dim_c},
  8. 矩形盒 = function(Dim_a, Dim_b, Dim_c) {Dim_a * Dim_b * Dim_c})
  9. 还可以使用`purrr::transpose`将数据框的每一行作为行创建一个列表:
  10. transpose(select(df1, c(Dim_a, Dim_b, Dim_c))
  11. 现在,您可以对`fun_list[df1$Shape]`和上面的行列表使用`purrr::map2`来应用`do.call`
  12. map2_dbl(fun_list[df1$Shape],
  13. transpose(select(df1, c(Dim_a, Dim_b, Dim_c))),
  14. do.call)
  15. 椭球体 矩形盒
  16. 2769.838 4680.000

请注意,我已经将"Ellipsoid"和"Rectangular_box"分别翻译为"椭球体"和"矩形盒",以使代码更具可读性。

英文:

Dummy data:

  1. library(tidyverse)
  2. df1 &lt;- tribble(~Shape, ~Dim_a, ~Dim_b, ~Dim_c,
  3. &quot;Ellipsoid&quot;, 23, 10, 23,
  4. &quot;Rectangular_box&quot;, 4, 65, 18)

You can create a list with your functions (with the same name as "shape"):

  1. fun_list &lt;- list(Ellipsoid = function(Dim_a, Dim_b, Dim_c) {(pi/6) * Dim_a * Dim_b * Dim_c},
  2. Rectangular_box = function(Dim_a, Dim_b, Dim_c) {Dim_a * Dim_b * Dim_c})

And a list with every row of your dataframe as rows using purrr::transpose:

  1. transpose(select(df1, c(Dim_a, Dim_b, Dim_c))

Now you can apply do.call to every combination of fun_list[df1$Shape], and the row list above, using purrr::map2:

  1. map2_dbl(fun_list[df1$Shape],
  2. transpose(select(df1, c(Dim_a, Dim_b, Dim_c))),
  3. do.call)
  4. Ellipsoid Rectangular_box
  5. 2769.838 4680.000

答案4

得分: 0

For 2 options, ifelse is a great option. If you want something more extendable, case_when or case_match are better.

mutate, case_when, 和 case_match 都来自于 dplyr 包,而 case_match 需要一个相对较新的版本。

如果你的决策只基于形状并且你有一个较新版本的 dplyr,case_match 可能会更清晰一些

  1. df %>%
  2. mutate(
  3. vol = case_match(Shape,
  4. "Ellipsoid" ~ (pi/6) * Dim_a * Dim_b * Dim_c,
  5. "Rectangular_box" ~ Dim_a * Dim_b * Dim_c,
  6. "Pyramid" ~ Dim_a * Dim_b * Dim_c / 3,
  7. .default ~ NA # 默认行为,在此处可修改
  8. )
  9. )

如果你的条件基于多个变量,case_when 更灵活

  1. df %>%
  2. mutate(
  3. vol = case_when(
  4. Shape == "Ellipsoid" ~ (pi/6) * Dim_a * Dim_b * Dim_c,
  5. Shape == "Rectangular_box" ~ Dim_a * Dim_b * Dim_c,
  6. Shape == "Pyramid" ~ Dim_a * Dim_b * Dim_c / 3,
  7. TRUE ~ NA # 默认行为,在此处可修改
  8. )
  9. )

使用任何一个函数,你可以添加任意数量的形状(例如我添加的金字塔示例)。

英文:

For 2 options, ifelse is a great option. If you want something more extendable, case_when or case_match are better.

mutate, case_when, and case_match are all from the dplyr package, with case_match requiring a pretty recent version.

case_match is probably a bit cleaner if you're decision is based only on Shape, and you have a recent version of dplyr

  1. df %&gt;%
  2. mutate(
  3. vol = case_match(Shape,
  4. &quot;Ellipsoid&quot; ~ (pi/6) * Dim_a * Dim_b * Dim_c,
  5. &quot;Rectangular_box&quot; ~ Dim_a * Dim_b * Dim_c,
  6. &quot;Pyramid&quot; ~ Dim_a * Dim_b * Dim_c / 3,
  7. .default ~ NA # default behavior, but modifiable here
  8. )
  9. )

case_when is more flexible if your conditions are based on more than one variable

  1. df %&gt;%
  2. mutate(
  3. vol = case_when(
  4. Shape == &quot;Ellipsoid&quot; ~ (pi/6) * Dim_a * Dim_b * Dim_c,
  5. Shape == &quot;Rectangular_box&quot; ~ Dim_a * Dim_b * Dim_c,
  6. Shape == &quot;Pyramid&quot; ~ Dim_a * Dim_b * Dim_c / 3,
  7. TRUE ~ NA # default behavior, but modifiable here
  8. )
  9. )

Using either function, you can as many shapes as you need (e.g. the pyramid example I added)

huangapple
  • 本文由 发表于 2023年6月6日 01:47:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76408847.html
匿名

发表评论

匿名网友

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

确定