如何将函数应用于data.frame的每个元素?
我想将一个数值转换成一个因子,如果该值低于-2,则“向下”应为因子,如果该值高于2,则“向上”并介于“无变化”之间: 到目前为止,我考虑创建一个函数:如何将函数应用于data.frame的每个元素?,r,R,我想将一个数值转换成一个因子,如果该值低于-2,则“向下”应为因子,如果该值高于2,则“向上”并介于“无变化”之间: 到目前为止,我考虑创建一个函数: classifier <- function(x){ if (x >= 2){ return(as.factor("up")) }else if (x <= -2){ return(as.factor("down")) }else { return(as.factor(
classifier <- function(x){
if (x >= 2){
return(as.factor("up"))
}else if (x <= -2){
return(as.factor("down"))
}else {
return(as.factor("no_change"))
}
}
我通常不喜欢
ifelse()
,所以我可能会引入一个新的向量,并以不同的方式处理这个问题
factorized <- rep("no_change", length(mock_data))
factorized[mock_data > 2] <- "up"
factorized[mock_data < -2] <- "down"
factorized <- as.factor(factorized)
#> factorized
#[1] no_change no_change no_change down up up down down up no_change no_change up no_change no_change up
#Levels: down no_change up
factorized 2]使用带有行和列标识符的apply
apply(yourDF, c(1, 2), classifier)
这用于将函数应用于data.frame
的每个单元格。它可能对向量不起作用 使用DF我不知道它可以用于所有的data.frame,谢谢!那以后可能会派上用场on@Llopis事实上,apply
在一个数组上工作,返回取决于应用程序生成的内容。它对data.frame输入调用as.matrix
,从而将不同类型的列强制为同一类型。我希望这是最快的解决方案之一,但函数的目的是针对这种情况。谢谢你指出这一点。@Llopis,没有。我还没有测试过,但我确信RHertel的答案会更快。这只是基本的子集设置,这将是非常有效的。我希望看到这些的基准,我的data.frames可以有20532行和1000列。。。越快越好:)@Llopis,完成了。正如你在我的回答中所看到的,基准测试通常很容易做到。你可能对我回答中的基准测试感兴趣。这确实很有趣。非常感谢,@AnandaMahto
mock_data <- c(1.11004611710086, -1.86842617811635, 1.72159335808828, -2.68788822228089,
2.72551498375833, 3.67290901951492, -4.00984475389123, -2.39582793787122,
4.22395745059475, -0.360892189200968, 1.35027756914496, 2.89919016882777,
-0.158692332915962, -0.950306688901037, 3.39141107397154)
apply(yourDF, c(1, 2), classifier)
DF[] <- lapply(DF, cut, c(-Inf, -2, 2, Inf), c("down", "no_change", "up"))
head(DF)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 up up no_change no_change
## 2 up up no_change no_change
## 3 up up no_change no_change
## 4 up up no_change no_change
## 5 up up no_change no_change
## 6 up up no_change no_change
tail(DF)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 145 up up up up
## 146 up up up up
## 147 up up up no_change
## 148 up up up no_change
## 149 up up up up
## 150 up up up no_change
cut(mock_data, c(-Inf, -2, 2, Inf), c("down", "no_change", "up"))
## [1] no_change no_change no_change down up up down
## [8] down up no_change no_change up no_change no_change
## [15] up
## Levels: down no_change up
set.seed(1)
nrow = 20000
ncol = 1000
x <- as.data.frame(matrix(runif(nrow * ncol, min=-5, max=5), ncol = ncol))
factorize <- function(invec) {
factorized <- rep("no_change", length(invec))
factorized[invec > 2] <- "up"
factorized[invec < -2] <- "down"
factor(factorized, c("down", "no_change", "up"))
}
RHfun <- function(indf = x) {
indf[] <- lapply(indf, factorize)
indf
}
AMfun <- function(DF = x) {
DF[] <- lapply(DF, cut, c(-Inf, -2, 2, Inf), c("down", "no_change", "up"))
DF
}
library(microbenchmark)
microbenchmark(AMfun(), RHfun(), times = 10)
# Unit: seconds
# expr min lq mean median uq max neval
# AMfun() 7.501814 8.015532 8.852863 8.731638 9.660191 10.198983 10
# RHfun() 1.437696 1.485791 1.723402 1.574507 1.637139 2.528574 10