[英]lapply() to use a function over multiple columns of a dataframe
我正在跟蹤一段時間內個體的體重,下面的函數使我可以計算相對於初始值(本質上是特定天的體重除以體重)得出的某天某人的體重百分比。在第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')"
有什么想法嗎?
這樣合適嗎
由於可以對相對百分比部分進行矢量化處理,因此我們可以大大簡化事情。
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
在這種情況下,您實際上不需要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
有一個在使用超級簡單的選擇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”語句處理,從而消除了僅指定一列的情況。 希望您不關心后者!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.