[英]mutate_at on multiple sets of columns with different functions
我定義了必須應用於不同組 dataframe 列的函數。 例如, mtcars
我想將as.integer()
function 應用於列c("mpg", "cyl")
和as.logical()
到c("vs", "am")
library(dplyr)
mtcars %>%
mutate_at(c("mpg", "cyl"), as.integer) %>%
mutate_at(c("vs", "am"), as.logical)
有什么做法,最好使用 tidyverse,用相應的函數保存此列集並應用它們而不使用mutate_at
多次。
這是我接近它的方式。 結果是可用於進一步覆蓋現有列或創建新列或用作獨立數據 object 的矩陣列表。
vars <- list(van = c("mpg", "cyl"),
tu = c("vs", "am"))
funk <- list(van = as.integer,
tu = as.logical)
mapply(FUN = function(v, f) {
sapply(mtcars[, v], FUN = f)
}, v = vars, f = funk, SIMPLIFY = FALSE)
$van
mpg cyl
[1,] 21 6
[2,] 21 6
[3,] 22 4
[4,] 21 6
[5,] 18 8
...
$tu
vs am
[1,] FALSE TRUE
[2,] FALSE TRUE
[3,] TRUE TRUE
[4,] TRUE FALSE
[5,] FALSE FALSE
...
要覆蓋現有列,您可以使用“可怕的”for 循環。 :)
mtcars[colnames(out$van)] <- out$van
mtcars[colnames(out$tu)] <- out$tu
# in generalized form
for (i in seq_along(out)) {
mtcars[colnames(out[[i]])] <- out[[i]]
}
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.90 2.620 16.46 FALSE TRUE 4 4
Mazda RX4 Wag 21 6 160 110 3.90 2.875 17.02 FALSE TRUE 4 4
Datsun 710 22 4 108 93 3.85 2.320 18.61 TRUE TRUE 4 1
Hornet 4 Drive 21 6 258 110 3.08 3.215 19.44 TRUE FALSE 3 1
Hornet Sportabout 18 8 360 175 3.15 3.440 17.02 FALSE FALSE 3 2
Valiant 18 6 225 105 2.76 3.460 20.22 TRUE FALSE 3 1
或者在一個循環中完成所有事情(更短)。
for (i in seq_along(vars)) {
cls <- vars[[i]]
f <- funk[[i]]
mtcars[, cls] <- sapply(mtcars[, cls], FUN = f)
}
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.90 2.620 16.46 FALSE TRUE 4 4
Mazda RX4 Wag 21 6 160 110 3.90 2.875 17.02 FALSE TRUE 4 4
Datsun 710 22 4 108 93 3.85 2.320 18.61 TRUE TRUE 4 1
Hornet 4 Drive 21 6 258 110 3.08 3.215 19.44 TRUE FALSE 3 1
Hornet Sportabout 18 8 360 175 3.15 3.440 17.02 FALSE FALSE 3 2
Valiant 18 6 225 105 2.76 3.460 20.22 TRUE FALSE 3 1
我正要提出@Roman Lustrik 在他答案的最后一部分中使用的相同方法,但這是在我打字之間完成的:)。 當我在這里時,我想我可以給 R 的 switch() function 一些愛,它也可以完成這項工作。
for (i in colnames(mtcars)) {
mtcars[, i] = switch(i,
mpg = as.integer(mtcars[, i]),
cyl = as.integer(mtcars[, i]),
vs = as.logical(mtcars[, i]),
am = as.logical(mtcars[, i]))
}
> head(mtcars)
mpg cyl vs am
Mazda RX4 21 6 FALSE TRUE
Mazda RX4 Wag 21 6 FALSE TRUE
Datsun 710 22 4 TRUE TRUE
Hornet 4 Drive 21 6 TRUE FALSE
Hornet Sportabout 18 8 FALSE FALSE
Valiant 18 6 TRUE FALSE
編輯:
由於 switch() function 如果沒有給出默認值,則會產生刪除列的副作用,並且 OP 要求保留所有列......這是解決方案:
for (i in colnames(mtcars)) {
mtcars[, i] = switch(i,
mpg = as.integer(mtcars[, i]),
cyl = as.integer(mtcars[, i]),
vs = as.logical(mtcars[, i]),
am = as.logical(mtcars[, i]),
mtcars[, i]) # just add a default option
}
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.90 2.620 16.46 FALSE TRUE 4 4
Mazda RX4 Wag 21 6 160 110 3.90 2.875 17.02 FALSE TRUE 4 4
Datsun 710 22 4 108 93 3.85 2.320 18.61 TRUE TRUE 4 1
Hornet 4 Drive 21 6 258 110 3.08 3.215 19.44 TRUE FALSE 3 1
Hornet Sportabout 18 8 360 175 3.15 3.440 17.02 FALSE FALSE 3 2
Valiant 18 6 225 105 2.76 3.460 20.22 TRUE FALSE 3 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.