Подтвердить что ты не робот

Исключение столбцов из фрейма данных на основе сумм столбцов

Я работаю над набором данных, который включает данные сообщества, а многие из столбцов (видов) имеют множество нулей. Я хотел бы иметь возможность отбросить эти столбцы для некоторых анализов, которые я делаю, исходя из суммы всего столбца. Я соблазн сделать это с помощью цикла for, но я слышал, что применение и функции лучше, когда вы используете R. Моя цель - удалить все столбцы с суммой менее 15. Я использовал which() для удаления строк по факторам, например,

September<-which(data$Time_point=="September")

data<-data[-September,] 

и два способа, которыми я попытался удалить столбцы, - это использовать apply():

data<-data[,apply(data,2,function(x)sum(x<=15))]

и с помощью коммисивного цикла /if else combo:

for (i in 6:length(data)){
    if (sum(data[,i])<=15)
    data[,i]<-NULL
    else 
    data[,i]<-data[,i]
    }

Ни один из этих методов не работает. Разумеется, есть элегантный способ избавиться от столбцов на основе логических критериев?

str(head(data,10))
'data.frame':   10 obs. of  23 variables:
 $ Core_num    : Factor w/ 159 levels "152","153","154",..: 133 72 70 75 89 85 86 90 95 99
 $ Cage_num    : num  0 1 2 3 4 5 6 7 8 9
 $ Treatment   : Factor w/ 4 levels "","C","CC","NC": 1 2 2 2 2 2 2 2 2 2
 $ Site        : Factor w/ 10 levels "","B","B07","B08",..: 1 8 8 8 7 7 7 7 9 9
 $ Time_point  : Factor w/ 3 levels "","May","September": 1 2 2 2 2 2 2 2 2 2
 $ Spionidae   : num  108 0 0 0 0 0 0 0 0 0
 $ Syllidae    : num  185 0 0 0 3 8 0 1 4 1
 $ Opheliidae  : num  424 0 1 0 0 0 1 1 0 0
 $ Cossuridae  : num  164 0 7 3 0 0 0 0 0 0
 $ Sternaspidae: num  214 0 0 6 1 0 11 9 0 0
 $ Sabellidae  : num  1154 0 2 2 0 ...
 $ Capitellidae: num  256 1 10 17 0 3 0 0 0 0
 $ Dorvillidae : num  21 1 0 0 0 0 0 0 0 0
 $ Cirratulidae: num  17 0 0 0 0 0 0 0 0 0
 $ Oligochaeta : num  3747 12 41 27 32 ...
 $ Nematoda    : num  410 5 4 13 0 0 0 2 2 0
 $ Sipuncula   : num  33 0 0 0 0 0 0 0 0 0
 $ Ostracoda   : num  335 0 1 0 0 0 0 0 0 0
 $ Decapoda    : num  62 0 4 0 1 0 0 0 0 0
 $ Amphipoda   : num  2789 75 17 34 89 ...
 $ Copepoda    : num  75 0 0 0 0 0 0 0 0 0
 $ Tanaidacea  : num  84 0 0 0 1 0 0 0 0 0
 $ Mollusca    : int  55 0 4 0 0 0 0 0 0 0
4b9b3361

Ответ 1

Как насчет простого подмножества? Во-первых, мы создаем простую структуру данныхL

R> dd = data.frame(x = runif(5), y = 20*runif(5), z=20*runif(5))

Затем выберите столбцы, где сумма больше 15

R> dd1 = dd[,colSums(dd) > 15]
R> ncol(dd1)
[1] 2

В вашем наборе данных вы хотите только подмножество столбцов 6, поэтому что-то вроде:

 ##Drop the first five columns
 dd[,colSums(dd[,6:ncol(dd)]) > 15]

или

 #Keep the first six columns
 cols_to_drop = c(rep(TRUE, 5), dd[,6:ncol(dd)]>15)
 dd[,cols_to_drop]

должен работать.


Ключевой частью, которую следует отметить, является то, что в квадратных скобках нам нужен вектор логических элементов, т.е. вектор TRUE и FALSE. Поэтому, если вы хотите подмножество, используя что-то более сложное, затем создайте функцию, которая возвращает TRUE или FALSE и подмножество, как обычно.

Ответ 2

Вы должны иметь возможность напрямую индексировать ваш data.frame с помощью boolean и colSums(). Например:

set.seed(123)
dat <- data.frame(var1 = runif(10), var2 = rnorm(10), var3 = rlnorm(10))
colSums(dat)
#-----
     var1      var2      var3 
 5.782475  1.317914 12.91987
#Let set the threshold at 5, so we should get var1 and var3
> dat[, colSums(dat) > 5]
#-----
        var1      var3
1  0.2875775 5.9709924
2  0.7883051 1.6451811
3  0.4089769 0.1399294
...

EDIT - для адресации нечисловых столбцов

set.seed(123)
dat <- data.frame(var1 = runif(10), var2 = rnorm(10), var3 = rlnorm(10), var4 = "notNumeric")

require(plyr)
dat[, -which(numcolwise(sum)(dat) < 5)]

Consolec:/документы и настройки /charles/desktop/

> dat[, -which(numcolwise(sum)(dat) < 5)]
        var1      var3       var4
1  0.2875775 5.9709924 notNumeric
2  0.7883051 1.6451811 notNumeric
3  0.4089769 0.1399294 notNumeric
.....

Ответ 3

Это приведет к возврату столбцов, которые не содержат всех нулей, включая коэффициенты и столбцы символов (я читаю только в первой строке chunky вашей информации):

Прочитайте некоторые из ваших данных:

dat <- read.table(text="  Core_num Cage_num Treatment Site Time_point Spionidae Nereididae Syllidae Opheliidae
6        24        1         C   M2        May         0          0        0          0
4        22        2         C   M2        May         0          0        0          1
9        27        3         C   M2        May         0          0        0          0
23       41        4         C    M        May         0          0        3          0
19       37        5         C    M        May         0          0        8          0
20       38        6         C    M        May         0          0        0          1",  header=T)

Код:

summer <- function(x){
    if(is.numeric(x)){
        sum(x) > 15
    } else {
        TRUE
    }
}

dat[, sapply(dat,  summer)]

Ответ 4

У меня просто была такая же проблема. Вот решение с использованием Tidyverse, если у вас есть как числовые, так и не числовые столбцы:

library(tidyverse)    
set.seed(123)
dat <- data.frame(var1 = runif(10), var2 = rnorm(10), var3 = rlnorm(10), var4 = "notNumeric", var5 =0, var6 = FALSE )

dat %>% 
  select_if(negate(function(col) is.numeric(col) && sum(col) < 15))