我正在跟踪一段时间内个体的体重,下面的函数使我可以计算相对于初始值(基本上是将特定天的体重除以除以第1天观察到的体重。
variability <- function(df, column_number) {
variable_name <- paste0("var_BW", column_number)
df %>%
mutate(!!variable_name := round(100*(df[,column_number]/df[1,column_number]), 1))
}
如果我在一列上使用此函数,它将很好用,但是由于我有很多人,所以我想使用apply()系列在一个数据帧的多个列上使用该函数(例如,在第1列上) :以下数据框的8:)
BW1 BW2 BW3 BW4 BW5 BW6 BW7 BW8
1 18.4 19.6 20.7 17.4 18.7 18.9 19.0 17.8
2 18.1 19.3 20.0 17.5 18.3 19.4 19.5 18.0
3 17.7 18.9 20.4 17.3 18.3 19.2 19.3 17.9
我最初的猜测是将列号存储在列表中,然后将该列表作为参数传递给lapply()函数,例如:
l <- list(1:8)
lapply(working_df, variability, l)
但是,当我这样做时,出现以下错误:
Error in UseMethod("mutate_") :
no applicable method for 'mutate_' applied to an object of class "c('double', 'numeric')"
有什么想法吗?
答案 0 :(得分:0)
这合适吗?
由于可以对相对百分比部分进行矢量化处理,因此可以大大简化事情。
bw <- read.table(text="
BW1 BW2 BW3 BW4 BW5 BW6 BW7 BW8
1 18.4 19.6 20.7 17.4 18.7 18.9 19.0 17.8
2 18.1 19.3 20.0 17.5 18.3 19.4 19.5 18.0
3 17.7 18.9 20.4 17.3 18.3 19.2 19.3 17.9", header=TRUE)
apply(bw, 2, function(x) round(100*x/x[1], 1))
# BW1 BW2 BW3 BW4 BW5 BW6 BW7 BW8
# 1 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0
# 2 98.4 98.5 96.6 100.6 97.9 102.6 102.6 101.1
# 3 96.2 96.4 98.6 99.4 97.9 101.6 101.6 100.6
或使用sweep()
round(sweep(bw, 2, unlist(bw[1,]), "/")*100, 1)
# BW1 BW2 BW3 BW4 BW5 BW6 BW7 BW8
# 1 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0
# 2 98.4 98.5 96.6 100.6 97.9 102.6 102.6 101.1
# 3 96.2 96.4 98.6 99.4 97.9 101.6 101.6 100.6
或更简单
round(100 * t(t(bw) / as.matrix(bw)[1,]), 1)
# BW1 BW2 BW3 BW4 BW5 BW6 BW7 BW8
# 1 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0
# 2 98.4 98.5 96.6 100.6 97.9 102.6 102.6 101.1
# 3 96.2 96.4 98.6 99.4 97.9 101.6 101.6 100.6
答案 1 :(得分:0)
在这种情况下,您实际上并不需要apply
。
pctvals <- round(100.0 * bw[,1:ncol(bw)] / bw[,1], 2)
收益
BW1 BW2 BW3 BW4 BW5 BW6 BW7 BW8
1 100 106.52 112.50 94.57 101.63 102.72 103.26 96.74
2 100 106.63 110.50 96.69 101.10 107.18 107.73 99.45
3 100 106.78 115.25 97.74 103.39 108.47 109.04 101.13
答案 2 :(得分:0)
使用mutate_at
软件包中的dplyr
有一个非常简单的选择:
library(dplyr)
working_df <-
data.frame(BW1 = c(18.4, 18.1, 17.7),
BW2 = c(19.6, 19.3, 18.9),
BW3 = c(20.7, 20.0, 20.4))
variability_v2 <- function(df, column_numbers) {
df %>%
mutate_at(vars(column_numbers), funs(var = round(100*(./first(.)), 1)))
}
variability_v2(working_df, 1:3)
#> BW1 BW2 BW3 BW1_var BW2_var BW3_var
#> 1 18.4 19.6 20.7 100.0 100.0 100.0
#> 2 18.1 19.3 20.0 98.4 98.5 96.6
#> 3 17.7 18.9 20.4 96.2 96.4 98.6
使用此方法的仅有2个(在我看来是非常小的问题):
前者可以通过函数中的简单“ if”语句处理,从而消除了仅指定一列的情况。希望您不关心后者!