2016-07-15 3 views
0

я чувствую себя очень глупо сейчас, но я не могу придумать более для петли ...R: эффективный способ применить функцию по столбцам dataframe

У меня есть кадр данных с числовыми и факториальными столбцами. Я просто хочу, чтобы числовые столбцы были масштабированы, а факториальные столбцы должны храниться как есть. Например

> set.seed(160) 
> df1 <- data.frame(as.data.frame(matrix(rnorm(8), ncol=2)), 
        V3=factor(c("A", "A", "B", "B"))) 
> df1 
      V1   V2 V3 
1 0.6185496 -0.6410203 A 
2 -0.8722777 2.6520986 A 
3 0.8529240 -1.4156009 B 
4 0.3678875 -1.1615607 B 

Я хотел бы получить

> df1 
      V1   V2 V3 
1 0.4901808 -0.2642698 A 
2 -1.4493527 1.4780179 A 
3 0.7950968 -0.6740765 B 
4 0.1640750 -0.5396717 B 

с более эффективной командой, чем

for(i in 1:ncol(df1)) { 
    if(is.factor(df1[,i])) {df1[,i] <- df1[,i]} 
    else{df1[,i] <- scale(df1[,i])} 
} 

Я пробовал различные комбинации из lapply(), sapply(), if(), ifelse(), но ничего не помогало (apply Безразлично» t, потому что df преобразуется в матрицу, и я теряю фактор/числовую структуру). Какие-либо предложения?

NB: Я не пытаюсь применить функцию, основанную на значений в столбцы, но на основе типа колонны.

+2

'индекс <- sapply (df1, is.factor); df1 [index] <- scale (df1 [index]) ', но он по-прежнему не по теме ;-) –

+0

Ops, я думал, что отправляю на SE;) спасибо в любом случае! – jeiroje

ответ

1

Вы можете попробовать следующее, который похож на предложение в комментариях:

df1[sapply(df1, is.numeric)] <- scale(df1[sapply(df1, is.numeric)]) 
#> df1 
#   V1   V2 V3 
#1 0.4901808 -0.2642698 A 
#2 -1.4493527 1.4780179 A 
#3 0.7950968 -0.6740765 B 
#4 0.1640750 -0.5396717 B 
0

Это должно сработать.

df1[] <- sapply(df1, function(i) if(is.numeric(i)) scale(i) else i) 
Смежные вопросы