gpt4 book ai didi

r - 如何在dplyr中使用多列实现一个函数

转载 作者:行者123 更新时间:2023-12-04 14:05:31 25 4
gpt4 key购买 nike

这个问题之前被问过:How to round numbers of a data frame in R preserving the sum?

我还想在 dplyr 中实现这个函数,它根据所需的位数进行舍入并保持统一:

round_preserve_sum <- function(x, digits = 0) {
up <- 10 ^ digits
x <- x * up
y <- floor(x)
indices <- tail(order(x-y), round(sum(x)) - sum(y))
y[indices] <- y[indices] + 1
y / up
}

这是一个数据框:

df <- data.frame(SAND = c(0.00000, 28.00000, 27.27273),
SILT = c(45.45455, 35.00000, 34.34343),
CLAY = c(54.54545, 37.00000, 38.38384))

分别使用这个函数和这些值,我得到:

round_preserve_sum(c(0.00000, 45.45455, 54.54545), 0)

[1] 0 45 55

 round_preserve_sum(c(28.00000, 35.00000, 37.00000), 0)

[1] 28 35 37

 round_preserve_sum(c(27.27273, 34.34343, 38.38384), 0)

[1] 27 34 39

总和为 100

当我在 dplyr 中实现这个功能时:

df.Rd0 <-df %>% 
mutate(across(c(SAND, SILT, CLAY), ~round_preserve_sum(.,0)),
Sum = SAND + SILT + CLAY)

我明白了:

   SAND SILT CLAY  Sum 
1 0 46 55 101
2 28 35 37 100
3 27 34 38 99

不使用代字号:

df.Rd0 <-df %>% 
mutate(across(c(SAND, SILT, CLAY), round_preserve_sum(.,0)),
Sum = SAND + SILT + CLAY)

我收到此错误消息:

Error : Problem with `mutate()` input `..1`.
i `..1 = across(c(SAND, SILT, CLAY), round_preserve_sum(., 0))`.
x undefined columns selected

我猜这个函数不是为向量编程的?

最佳答案

~ 是一个 lambda 表达式,即 function(.x) 的缩写形式。如果我们不使用它,则将格式参数指定为named one

library(dplyr)
df %>%
mutate(across(c(SAND, SILT, CLAY), round_preserve_sum, digits = 0),
Sum = SAND + SILT + CLAY)

-输出

  SAND SILT CLAY Sum
1 0 46 55 101
2 28 35 37 100
3 27 34 38 99

关于 OP 手动使用将总和设为 100,它是 rowwise,而不是 column wise - across 在列上循环。我们需要 rowwisec_across

df %>%
rowwise %>%
mutate(Sum = sum(round_preserve_sum(c_across(everything()), 0))) %>%
ungroup

-输出

# A tibble: 3 x 4
SAND SILT CLAY Sum
<dbl> <dbl> <dbl> <dbl>
1 0 45.5 54.5 100
2 28 35 37 100
3 27.3 34.3 38.4 100

如果我们想要将四舍五入的列与总和一起返回,请使用 pmap

library(purrr)
df %>%
pmap_dfr(~ {tmp <- round_preserve_sum(c(...), 0)
c(tmp, Sum = sum(tmp))})
# A tibble: 3 x 4
SAND SILT CLAY Sum
<dbl> <dbl> <dbl> <dbl>
1 0 45 55 100
2 28 35 37 100
3 27 34 39 100

这可以通过 collapse 中的 dapply 变得更快

library(collapse)
df <- dapply(df, MARGIN = 1, FUN = round_preserve_sum, 0)
df$Sum <- rowSums(df, na.rm = TRUE)

关于r - 如何在dplyr中使用多列实现一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68672570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com