在r中的lapply循环内设置级别

时间:2010-09-09 00:17:14

标签: r lapply

我正在尝试从尾随空格中清除数据框中的因子变量。但是,在我的lapply函数中,级别赋值不起作用。

rm.space<-function(x){
    a<-gsub(" ","",x)
    return(a)}


lapply(names(barn),function(x){
    levels(barn[,x])<-rm.space(levels(barn[,x]))
    })

如何在lapply函数中分配级别?

//中号

3 个答案:

答案 0 :(得分:6)

R是矢量化的,您不需要apply()

> f <- as.factor(sample(c("  a", " b", "c", "  d"), 10, replace=TRUE))                                                                                                             
> levels(f)                                                                                                                                                                        
[1] "  a" " b"  "c"   "  d"                                                                                                                                                        
> levels(f) <- gsub(" +", "", levels(f), perl=TRUE)                                                                                                                                
> levels(f)                                                                                                                                                                        
[1] "a" "b" "c" "d"                                                                                                                                                                
> f                                                                                                                                                                                
 [1] d a c b c d d a a a                                                                                                                                                           
Levels: a b c d                                                                                                                                                                    
>

答案 1 :(得分:1)

从你的代码我读到,lapply用于循环不同的变量,而不是在因子的级别上。那么你确实需要某种循环结构,但lapply是一个糟糕的选择:

  • 你循环遍历vector -names(barn) - 所以最好使用sapply
  • apply系列将返回每个循环的结果,这是你不想要的。所以你没有目的地使用记忆。

无论如何,如果您需要在lapply中为全局环境中的变量赋值,则需要&lt;&lt; - 运算符。假设您需要在必须删除空格的位置选择多个变量:

f <- paste("",letters[1:5])

Df <- data.frame(
    X1 = sample(f,10,r=T),
    X2 = sample(f,10,r=T),
    X3 = sample(f,10,r=T)
    )

# Bad example :   
lapply(c("X1","X3"),function(x){
    levels(Df[,x])<<-gsub(" +","",levels(Df[,x]))
    })

给出

> str(Df)
'data.frame':   10 obs. of  3 variables:
 $ X1: Factor w/ 3 levels "a","b","c": 2 3 1 1 1 2 3 2 2 2
 $ X2: Factor w/ 5 levels " a"," b"," c",..: 4 5 4 2 5 5 1 2 5 3
 $ X3: Factor w/ 5 levels "a","b","c","d",..: 2 3 4 1 4 1 3 3 5 4

更好的是使用for循环:

for( i in c("X1","X3")){
    levels(Df[,i])<-gsub(" +","",levels(Df[,i]))
}

在没有&lt;&lt; - 操作符的麻烦且不必要地保存内存的情况下,您需要做什么。

答案 2 :(得分:0)

由于Joris声明lapply适用于data.frame的本地副本,因此它不会修改您的原始数据。但您可以使用它来替换您的数据:

barn[] <- lapply(barn, function(x) {
    levels(x) <- rm.space(levels(x))
    x
    })

当您在数据中使用不同类型并且只想修改factor时,它非常有用,例如:

factors <- sapply(barn, is.factor)
barn[factors] <- lapply(barn[factors], function(x) {
                    levels(x) <- rm.space(levels(x))
                    x
                 })