2010-09-09 4 views
1

Я пытаюсь очистить фактор-переменные в кадре данных из конечных пробелов. Однако назначение уровней не работает внутри моей функции lapply.настройка уровней внутри цикла lapply в r

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


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

Любые идеи о том, как я могу назначать уровни внутри функции lapply?

// М

+0

вы можете предоставить воспроизводимый пример ? Я пробовал ваш код с некоторыми тестовыми данными, и, похоже, работает нормально. можете ли вы уточнить, что не работает? – Ramnath

ответ

1

Из кода я прочитал, что lapply используется для перебора различных переменных, а не по уровням фактор. Таким образом, то вам нужно какое-то зацикливание структуры, но lapply плохой выбор:

  • You перебирает вектор -names (сарай) - так что лучше использовать sapply
  • Применить семью вернет результат из каждого цикла, чего вы не хотите. Таким образом, вы используете память без цели.

Во всяком случае, в случае, если вам нужно назначить что-то переменной в вашей глобальной окружающей среды в lapply, вам нужно < < - оператор. Скажем, вам нужно иметь несколько переменных, выбранных где пространства должны быть удалены:

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(i in c("X1","X3")){ 
    levels(Df[,i])<-gsub(" +","",levels(Df[,i])) 
} 

ли что вам нужно без хлопот < < - оператор и без необходимости держать память без необходимости.

+0

Thx Joris. Сначала я сделал это с помощью цикла for, но поощрял все книги, в которых говорилось, что все должно быть сделано в рамках .apply. Я решил, что попробую ... Я не знал об операторе << -. Thx снова. // M – Misha

+0

@Misha: Я знаю, что for-loops недовольны сообществом R, особенно для того, что они работают в глобальной среде. применимая семья избегает этого, делая его более безопасным для использования во многих случаях. Тем не менее, здесь вы хотите работать в своей глобальной среде, поэтому для цикла это правильный инструмент. См. Также: http://stackoverflow.com/questions/2275896/is-rs-apply-family-more-than-syntactic-sugar –

6

R является vectorised, вам не нужно 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                                          
> 
+0

Правда, R векторизован, но удаление пробелов не векторизовано по различным переменным в кадре данных. Это то, что нужно OP, я верю из его кода. –

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 
       }) 
Смежные вопросы