我正在研究包含社区数据的数据集,并且许多列(种类)都有很多零.基于整列的总和,我希望能够根据我正在进行的一些分析删除这些列.我很想用for循环来做这个,但我听说当你使用R时,apply和by功能会更好.我的目标是删除总和小于15的所有列.我习惯which()
删除按因子划分的行,例如,
September<-which(data$Time_point=="September")
data<-data[-September,]
Run Code Online (Sandbox Code Playgroud)
我尝试删除列的两种方法是使用apply()
:
data<-data[,apply(data,2,function(x)sum(x<=15))]
Run Code Online (Sandbox Code Playgroud)
并使用凌乱的for循环/ if else组合:
for (i in 6:length(data)){
if (sum(data[,i])<=15)
data[,i]<-NULL
else
data[,i]<-data[,i]
}
Run Code Online (Sandbox Code Playgroud)
这两种方法都没有奏效.当然有一种优雅的方法来摆脱基于逻辑标准的列?
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
Run Code Online (Sandbox Code Playgroud)
csg*_*pie 20
一个简单的子集怎么样?首先,我们创建一个简单的数据框架L.
R> dd = data.frame(x = runif(5), y = 20*runif(5), z=20*runif(5))
Run Code Online (Sandbox Code Playgroud)
然后选择总和大于15的列
R> dd1 = dd[,colSums(dd) > 15]
R> ncol(dd1)
[1] 2
Run Code Online (Sandbox Code Playgroud)
在您的数据集中,您只想将列6向上集合,因此类似于:
##Drop the first five columns
dd[,colSums(dd[,6:ncol(dd)]) > 15]
Run Code Online (Sandbox Code Playgroud)
要么
#Keep the first six columns
cols_to_drop = c(rep(TRUE, 5), dd[,6:ncol(dd)]>15)
dd[,cols_to_drop]
Run Code Online (Sandbox Code Playgroud)
应该管用.
需要注意的关键部分是在方括号中,我们需要一个逻辑向量,即一个TRUE和FALSE的向量.因此,如果您想使用更复杂的东西进行子集化,那么创建一个像往常一样返回TRUE或FALSE和子集的函数.
小智 9
我刚刚遇到了同样的问题。如果您同时拥有数字列和非数字列,这是使用 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))
Run Code Online (Sandbox Code Playgroud)