R-цикл по фрейму данных и подсчет значений, превышающих значение, и удаление строк - PullRequest
0 голосов
/ 03 октября 2018

Я хочу пройтись по большим кадрам данных, подсчитывая в первом столбце, сколько значений> 0, удаляя те строки, которые были подсчитаны .... затем переходя к столбцу 2, считая количество значений> 0, удаляя эти строки и т. Д....

кадр данных

  taxonomy A B C
1      cat 0 2 0
2      dog 5 1 0
3    horse 3 0 0
4    mouse 0 0 4
5     frog 0 2 4
6     lion 0 0 2

может быть сгенерирован с помощью

DF1 = structure(list(taxonomy = c("cat", "dog","horse","mouse","frog", "lion"),
                A = c(0L, 5L, 3L, 0L, 0L, 0L), D = c(2L, 1L, 0L, 0L, 2L, 0L), C = c(0L, 0L, 0L, 4L, 4L, 2L)), 
                .Names = c("taxonomy", "A", "B", "C"), 
                row.names = c(NA, -6L), class = "data.frame")

, и я ожидаю, что результат будет

      A B C
count 2 2 2

я написал этот цикл, но он не удаляет строки, поскольку он идет

res <- data.frame(DF1[1,], row.names = c('count'))
for(n in 1:ncol(DF1)) {
  res[colnames(DF1)[n]] <- sum(DF1[n])
  DF1[!DF1[n]==1] 
  }

он дает этот неверный результат

      A B C
count 2 3 3

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Вы могли бы сделать ...

DF = DF1[, -1]
cond = DF != 0
p = max.col(cond, ties="first")
fp = factor(p, levels = seq_along(DF), labels = names(DF))
table(fp)

# A B C 
# 2 2 2 

Чтобы учесть строки, которые являются всеми нулями, я думаю, что это работает:

fp[rowSums(cond) == 0] <- NA
0 голосов
/ 03 октября 2018

Это легко с Reduce и sapply:

> first <- Reduce(function(a,b) b[a==0], df[-1], accumulate=TRUE)
> first
[[1]]
[1] 0 5 3 0 0 0

[[2]]
[1] 2 0 2 0

[[3]]
[1] 0 4 2

> then <- sapply(setNames(first, names(df[-1])), function(x) length(x[x>0]))
> then
A B C 
2 2 2 
0 голосов
/ 03 октября 2018

Мы можем обновлять набор данных при каждом запуске.Создайте временный набор данных без столбца таксономии (tmp).Инициируйте named vector ('n'), просматривайте столбцы 'tmp', получите логический индекс, основанный на том, больше ли столбец 0 ('i1'), получите sum значений TRUEобновите 'n' для соответствующего столбца, затем обновите 'tmp', удалив эти строки, используя 'i1' в качестве индекса строки

tmp <- DF1[-1]
n <- setNames(numeric(ncol(tmp)), names(tmp))
for(i in seq_len(ncol(tmp))) {
           i1 <- tmp[[i]] > 0
           n[i] <- sum(i1)
           tmp <- tmp[!i1, ]}
n
#  A B C 
#  2 2 2 

Это также можно сделать с помощью Reduce

sapply(Reduce(function(x, y) y[!x] > 0, DF1[3:4],
         init = DF1[,2] > 0, accumulate = TRUE ), sum)
#[1] 2 2 2

Или с использованием accumulate из purrr

library(purrr)
accumulate(DF1[3:4], ~ .y[!.x] > 0, .init = DF1[[2]] > 0) %>% 
                 map_int(sum)
#[1] 2 2 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...