我正在尝试使用dplyr的mutate_at
从另一个对应的数字列(A1
)中减去数字列的值(A2
),我有多个列和多个数据帧想要为此做(BCDE ...,df1:df99),所以我想编写一个函数。
df1 <- df1 %>% mutate_at(.vars = vars(A1), .funs = funs(remainder = .-A2))
工作正常,但是当我尝试编写函数来执行此操作时:
REMAINDER <- function(df, numer, denom){
df <- df %>% mutate_at(.vars = vars(numer), .funs = funs(remainder = .-denom))
return(df)
}
带有参数df1 <- REMAINDER(df1, A1, A2)
我收到错误Error in mutate_impl(.data, dots) :
Evaluation error: non-numeric argument to binary operator.
我不理解,因为我只是手动调用没有功能的代码行,并且我的列都是数字。
答案 0 :(得分:0)
小插图Programming with dplyr详细说明了怎么做:
library(dplyr)
REMAINDER <- function(df, numer, denom) {
numer <- enquo(numer)
denom <- enquo(denom)
df %>% mutate_at(.vars = vars(!! numer), .funs = funs(remainder = . - !! denom))
}
df1 <- data_frame(A1 = 11:13, A2 = 3:1, B1 = 21:23, B2 = 8:6)
REMAINDER(df1, A1, A2)
# A tibble: 3 x 5 A1 A2 B1 B2 remainder <int> <int> <int> <int> <int> 1 11 3 21 8 8 2 12 2 22 7 10 3 13 1 23 6 12
REMAINDER(df1, B1, B2)
# A tibble: 3 x 5 A1 A2 B1 B2 remainder <int> <int> <int> <int> <int> 1 11 3 21 8 13 2 12 2 22 7 15 3 13 1 23 6 17
OP想要更新df1
,他也希望将此操作应用于其他列。
不幸的是,当前定义的REMAINDER()
函数将覆盖结果列:
df1
# A tibble: 3 x 4 A1 A2 B1 B2 <int> <int> <int> <int> 1 11 3 21 8 2 12 2 22 7 3 13 1 23 6
df1 <- REMAINDER(df1, A1, A2)
df1
# A tibble: 3 x 5 A1 A2 B1 B2 remainder <int> <int> <int> <int> <int> 1 11 3 21 8 8 2 12 2 22 7 10 3 13 1 23 6 12
df1 <- REMAINDER(df1, B1, B2)
df1
# A tibble: 3 x 5 A1 A2 B1 B2 remainder <int> <int> <int> <int> <int> 1 11 3 21 8 13 2 12 2 22 7 15 3 13 1 23 6 17
可以修改该函数,以便分别命名结果列:
REMAINDER <- function(df, numer, denom) {
numer <- enquo(numer)
denom <- enquo(denom)
result_name <- paste0("remainder_", quo_name(numer), "_", quo_name(denom))
df %>% mutate_at(.vars = vars(!! numer),
.funs = funs(!! result_name := . - !! denom))
}
现在,在不同的列上调用REMAINDER()
两次,并在每次调用后替换df1
,我们得到
df1 <- REMAINDER(df1, A1, A2)
df1 <- REMAINDER(df1, B1, B2)
df1
# A tibble: 3 x 6 A1 A2 B1 B2 remainder_A1_A2 remainder_B1_B2 <int> <int> <int> <int> <int> <int> 1 11 3 21 8 8 13 2 12 2 22 7 10 15 3 13 1 23 6 12 17
答案 1 :(得分:-1)
我已使用this suggestion来减去数据帧列表中的成对列。我的示例在两个数据帧中的每一个中只有3对列,并且可以使用更多的列和数据帧。
dt <- data.table(A1 = round(runif(3),1), A2 = round(runif(3),1),
B1 = round(runif(3),1), B2 = round(runif(3),1),
C1 =round(runif(3),1), C2 =round(runif(3),1))
dt = list(dt,dt+dt)
lapply(seq_along(dt), function(z) {
dt[[z]][, lapply(1:(ncol(.SD)/2), function(x) (.SD[[2*x-1]] - .SD[[2*x]]))]
})