2015-09-01 2 views
1

Я знаю, что вокруг есть много подобных вопросов, но я боюсь, что я не мог окунуться в эту конкретную сторону, хотя, очевидно, это очень просто!Как применить функцию ifelse по именам столбцов?

Я пытаюсь написать простую функцию ifelse, которая будет применяться к ряду столбцов в кадре данных, используя имена столбцов (а не числа). Я пытаюсь создать одну переменную u_all, как показано ниже, без повторного ввода имен столбцов.

dat <- data.frame(id=c(1:20),u1 = sample(c(0:1),20,replace=T) , u2 = sample(c(0:1),20,replace=T) , u3 = sample(c(0:1),20,replace=T)) 
dat<-within(dat,u_all<-ifelse (u1==1 | u2==1 |u3==1,1,0)) 
dat 

Я пробовал много вариантов apply, но ясно, что я не на правильном пути, так как эти группировки функции репликации функции ifelse на каждой колонке отдельно.

dat2 <- data.frame(id=c(1:20),u1 = sample(c(0:1),20,replace=T) , u2 = sample(c(0:1),20,replace=T) , u3 = sample(c(0:1),20,replace=T)) 

dat2<-cbind(dat2,sapply(dat2[,grepl("^u\\d{1,}",colnames(dat2))], 
           function(x){ u_all<-ifelse(x==1 & !is.na(x),1,0)})) 

dat2 
+1

При попытке использовать имена столбцов, хранящиеся в переменных, ярлыки типа '$', 'with',' inside', 'subset' и т. Д. ** являются ** не ** вашим другом. используйте '' 'исключительно и все работает лучше. – Gregor

+0

@Gregor Спасибо! Но могу ли я спросить, почему? И вы хотите сказать, например, что я должен избегать использования ярлыка '' '' '(как в' dat $ u1') и вместо этого использовать 'dat [, 2]'? – Eva

+1

'dat $ u2' отлично, если' 'u2" '- это имя столбца. Но если 'u2 <-" mpg ",' mtcars $ u2' не будет работать, потому что '$' не оценивает 'u2', он ищет столбец с именем' 'u2" '. Но если 'u2 <-" mpg ",' mtcars [, u2] '** будет работать **, как и' mtcars [, "mpg"] '. См., Например, 'fortunes :: fortune (343)', 'fortunes :: fortune (312)' и предупреждение в '? Subset' ..., которое, вероятно, должно быть включено в'? With'. – Gregor

ответ

5

Эта линия от OP

dat<-within(dat,u_all<-ifelse (u1==1 | u2==1 |u3==1,1,0)) 

вместо этого может быть записана в виде

dat$u_all <- +Reduce("|", dat[, c("u1", "u2", "u3")]) 

Как это работает, с точки зрения промежуточных объектов:

  • D = dat[, c("u1", "u2", "u3")] использует имена столбцов для подмножества кадра данных.
  • r = Reduce("|", D) сворачивает данные, помещая | между каждой парой столбцов. Результатом является логический (TRUE/FALSE) вектор.
  • Для преобразования r в 0/1 целочисленном векторе, можно использовать ifelse(r,1L,0L) или as.integer(r) (с true/false новообращенных 1/0 по умолчанию) или только одноместной +, как +r.

Если вы хотите избегайте с использованием имен столбцов (это на самом деле не ясно для меня от должности), то можно построить D = dat[-1] исключить первый столбец вместо этого.

+2

Спасибо большое! Извините за то, что я не понимаю.Я не пытался избежать имен столбцов, напротив, я хочу, чтобы _use_ имена столбцов, но не хочу вводить один за другим, потому что есть много столбцов. Поэтому я просто отредактировал ваш код как 'dat $ u_all <- + Reduce (" | ", dat [, grepl ("^u \\ d {1,} ", colnames (dat))])' в моем скрипте. Работает отлично! – Eva

3

Вы были почти там, вот решение, используя применять более строки и использовать все, чтобы преобразовать вектор испытаний к одной цифре.

dat2$u_all <- apply(dat2[,-1], MARGIN=1, FUN=function(x){ 
    any(x==1)&all(!is.na(x))*1 
} 
) 
+0

Спасибо! Но это не кажется правильным. С помощью этого кода u_all принимает значение 1, только если все три переменные (u1, u2 и u3) равны 1. – Eva

+1

К сожалению. Изменено на 'any'. Предполагалось, что вы хотите проверить, не потерялись ли все значения, неуверенный, как вы хотите, чтобы они обрабатывались. – Heroka