即使它與sapply相關- 保留列名,我在那里找不到答案......
我有一個簡單的函式來在 0 和 1 之間縮放資料,保留列名:
scale <- function(x){apply(x, 2, function(y) ((y)-min(y, na.rm=TRUE))/(max(y, na.rm=TRUE)-min(y, na.rm=TRUE)))}
現在我需要為 max(y) = min(y) 的情況添加一個 if 子句,并像這樣更改函式:
scale <- function(x){apply(x, 2, function(y) if(min(y, na.rm=TRUE)==max(y, na.rm=TRUE)) {0.5} else {((y)-min(y, na.rm=TRUE))/(max(y, na.rm=TRUE)-min(y, na.rm=TRUE))})}
在像這樣的輸入資料幀上使用這些函式......
as.data.frame(scale(input[sapply(input,is.numeric)]))
產生不同的列名,其中原始函式保留名稱,新函式以括號或連字符替換為點的方式修改它們:
不帶 IF 的列名示例:INL_Avg(S-B0-ETC-CDS-06C~PM_CD1_D_B0_SI_P0V_B.NM)
帶有 IF 的示例列名稱:INL_Avg.S.B0.ETC.CDS.06C.PM_CD1_D_B0_SI_P0V_B.NM。
雖然我確實意識到這些列名并不理想,但它是我需要使用的,我希望得到有關如何避免這種特殊字符替換的提示(將 USE.NAMES=TRUE 添加到 sapply 無濟于事......) .
謝謝,馬克
uj5u.com熱心網友回復:
您問題的根源在于您正在使用apply資料框。apply專為處理矩陣而構建,因此它所做的第一件事是將您的資料框轉換為矩陣,這是不必要的,然后在您轉換回來時的默認資料框方法以一種您不需要的方式“修復”列名喜歡。您可以通過添加check.names = FALSE到您的as.data.frame()呼叫中來解決這個問題,但更好的方法是lapply在資料框、apply矩陣上使用,如果我們給它一個向量輸入,甚至可以讓它作業。
我還強烈建議不要scale用相似但不同的函式覆寫內置函式。這很容易導致錯誤。我已經重寫了呼叫它的函式scale01()以明確區分。
我還修改了它,所以如果輸入是一個帶有缺失值的常量向量,只有非缺失值會用 填充0.5,這看起來更安全。
我使用 S3 調度根據輸入類適當地作業,該類建立在default適用于數字向量的方法之上。這是在向量、data.frame 和矩陣輸入上演示的:
## defining the functions
scale01 = function(x, ...) {
UseMethod("scale01")
}
scale01.numeric = function(x, ...) {
minx = min(x, na.rm = TRUE)
maxx = max(x, na.rm = TRUE)
if(minx == maxx) {
x[!is.na(x)] = 0.5
return(x)
}
(x - minx) / (maxx - minx)
}
scale01.data.frame = function(x, ...) {
x[] = lapply(x, scale01)
x
}
scale01.matrix = function(x, ...) {
apply(x, MARGIN = 2, FUN = scale01)
}
## demonstrating usage
scale01(rnorm(5))
# [1] 0.0000000 1.0000000 0.4198958 0.6104154 0.2108150
scale01(mtcars[1:5, ])
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 0.5609756 0.5 0.2063492 0.2073171 1.00000000 0.2678571 0.0000000 0 1 1 1.0000000
# Mazda RX4 Wag 0.5609756 0.5 0.2063492 0.2073171 1.00000000 0.4955357 0.1879195 0 1 1 1.0000000
# Datsun 710 1.0000000 0.0 0.0000000 0.0000000 0.93902439 0.0000000 0.7214765 1 1 1 0.0000000
# Hornet 4 Drive 0.6585366 0.5 0.5952381 0.2073171 0.00000000 0.7991071 1.0000000 1 0 0 0.0000000
# Hornet Sportabout 0.0000000 1.0 1.0000000 1.0000000 0.08536585 1.0000000 0.1879195 0 0 0 0.3333333
scale01(as.matrix(mtcars[1:5, ]))
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 0.5609756 0.5 0.2063492 0.2073171 1.00000000 0.2678571 0.0000000 0 1 1 1.0000000
# Mazda RX4 Wag 0.5609756 0.5 0.2063492 0.2073171 1.00000000 0.4955357 0.1879195 0 1 1 1.0000000
# Datsun 710 1.0000000 0.0 0.0000000 0.0000000 0.93902439 0.0000000 0.7214765 1 1 1 0.0000000
# Hornet 4 Drive 0.6585366 0.5 0.5952381 0.2073171 0.00000000 0.7991071 1.0000000 1 0 0 0.0000000
# Hornet Sportabout 0.0000000 1.0 1.0000000 1.0000000 0.08536585 1.0000000 0.1879195 0 0 0 0.3333333
weird_name_df = data.frame(`weird column` = rnorm(5), `INL_Avg(S-B0-ETC-CDS-06C~PM_CD1_D_B0_SI_P0V_B.NM)` = rnorm(5), check.names = FALSE)
scale01(weird_name_df)
# weird column INL_Avg(S-B0-ETC-CDS-06C~PM_CD1_D_B0_SI_P0V_B.NM)
# 1 0.6135744 0.2237905
# 2 0.0000000 0.4086837
# 3 1.0000000 1.0000000
# 4 0.7061441 0.2803262
# 5 0.7693184 0.0000000
如果要轉換資料框的所有數字列,我建議:
## base version
numeric_cols = sapply(your_data, is.numeric)
your_data[numeric_cols] = scale01(your_data[numeric_cols])
## dplyr version
library(dplyr)
your_data %>%
mutate(across(where(is.numeric), scale01))
uj5u.com熱心網友回復:
在這里找到了解決方案:
as.data.frame(scale(input[sapply(input,is.numeric)]),check.names = FALSE)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/351224.html
上一篇:如何從實時中減去資料庫時間
下一篇:Rifelse陳述句忽略輸入
