2016-05-30 1 views
1

У меня есть следующий ДФ:условного расчета: длина определенной строки, когда ниже строка не значение NA

  X7 X8 X9 X10 X11 X12 X13 X14 
1   1 1 <NA> 1 1 1 1 <NA>  
2   1 1 1 1 1 1 <NA> <NA> 
3   1 1 1 1 1 <NA> <NA> <NA> 

Редактировать: Используя это:

df <- data.frame(X7=c(1L,1L,1L),X8=c(1L,1L,1L),X9=factor(c(NA,'1','1')),X10=c(1L,1L,1L),X11=c(1L,1L,1L),X12=factor(c('1','1',NA)),X13=factor(c('1',NA,NA)),X14=factor(c(NA,NA,NA))); 

Я хочу, чтобы вычислить длину строки 1, за исключением NA, когда значения в строке 2 не являются значениями NA. И затем сделайте то же самое для строки 1 и 3.

Таким образом, результат для строк 1-2 должен быть 5 и строки 1-3 должны быть 4.

Я понятия не имею, как идти об этом, кроме зная, как вычислить длину каждой строки:

(apply(df, MARGIN = 1, FUN = function(x) length(x[!is.na(x)]))) 

Любая помощь будет принята с благодарностью!

+2

Не должен ли результат для строк 1 и 2 быть 5? – bgoldst

+1

'' NA "' это не то же самое, что 'NA'. Ваш код создает матрицу символов, а не фрейм данных. –

+0

@RichardScriven - это правильно. Для моего ответа я создал собственное определение 'df', которое воспроизводит вывод печати, указанный в вопросе. Вызов 'cbind()', показанный в вопросе, вероятно, является источником непоследовательности и его следует игнорировать. – bgoldst

ответ

2

Я бы прекомпилировал логическую матрицу, представляющую, какие ячейки не NA, а затем перебираем все индексы строк за пределами первого номера с помощью вызова sapply(). Внутри лямбды вы можете сделать логическое И между текущей строкой и первой строкой, чтобы получить общие не-NA, а затем использовать sum(), чтобы подсчитать, сколько их есть.

df <- data.frame(X7=c(1L,1L,1L),X8=c(1L,1L,1L),X9=factor(c(NA,'1','1')),X10=c(1L,1L,1L),X11=c(1L,1L,1L),X12=factor(c('1','1',NA)),X13=factor(c('1',NA,NA)),X14=factor(c(NA,NA,NA))); 
nons <- !is.na(df); 
sapply(seq(2L,len=nrow(df)-1L),function(ri) sum(nons[1L,]&nons[ri,])); 
## [1] 5 4 

В качестве альтернативы, вы можете предвычисление индексов столбцов в первой строке, которые имеют не-NA, а затем внутри лямбда-вызов intersect() против индексов в текущей строке, которые имеют не-NA.

nons <- !is.na(df); 
nons1 <- unname(which(nons[1L,])); 
sapply(seq(2L,len=nrow(df)-1L),function(ri) length(intersect(nons1,which(nons[ri,])))); 
## [1] 5 4 
+2

Другим способом будет 'm <- t (! Is.na (df)); colSums (m [, 1] & m) [- 1] ' –

+1

Crap, well done @MaratTalipov! Я кратко размышлял о возможности достижения полностью векторизованного решения, но по какой-то причине решил, что это невозможно, поэтому рассчитан на 'sapply()'. Вы должны отправить ответ; Я бы поднял его. – bgoldst

+0

@MaratTalipov, чтобы иметь возможность рассчитать между строкой '2' -'3' внутри того же кода, я предполагаю, что мне придется его зацикливать. Большое спасибо, ребята! – Bonono

Смежные вопросы