如何同时按名称或标准偏差选择列?

3

解决方案

我采用了@thelatemail提供的解决方案,因为我正在尝试坚持使用tidyverse和dplyr,我还是R的新手,所以我正在采取渐进式的方法并利用辅助库。谢谢所有人抽出时间贡献解决方案。

df_new <- df_inh %>%
select(
  isolate,
  Phenotype,
  which(
    sapply( ., function( x ) sd( x ) != 0 )
  )
)

问题

我想选择列名为“isolate”或“Phenotype”,或者如果列值的标准差不为0,则选择该列。

我尝试了以下代码:

df_new <- df_inh %>%
# remove isolate and Phenotype column for now, don't want to calculate their standard deviation
select(
  -isolate,
  -Phenotype
) %>%
# remove columns with all 1's or all 0's by calculating column standard deviation
select_if(
  function( col ) return( sd( col ) != 0 )
) %>%
# add back the isolate and Phenotype columns
select(
  isolate,
  Phenotype
)

我也尝试了这个

df_new <- df_inh %>%
select_if(
  function( col ) {
  if ( col == 'isolate' | col == 'Phenotype' ) {
    return( TRUE )
  }
  else {
    return( sd( col ) != 0 )
  }
}
)

我可以通过标准差或列名选择列,但是我不能同时进行这两个操作。


请确保您的示例可重现。您需要使用 dput 命令包含至少一份数据样本,并将输出添加到您的问题中。 - morgan121
Base R 对于这个任务来说并不太糟糕 - dat[names(dat) %in% c("isolate","Phenotype") | sapply(dat, sd) != 0] 或者使用相同的逻辑在 dplyr 中也可以 - dat %>% select(isolate, Phenotype, which(sapply(., function(x) sd(x) != 0))) - thelatemail
@thelatemail 我选择了你的第二个解决方案: - Spencer A Lank
@thelatemail,顺便问一下,sapply()函数中的"."参数表示什么? - Spencer A Lank
@spence - 在这里,.代表由%>%传入的整个对象,本例中仅为数据集dat - thelatemail
2个回答

4

不确定能否仅使用select_if完成此操作,但一种方法是将两个select操作组合起来,然后绑定列。以mtcars作为样本数据。

library(dplyr)
bind_cols(mtcars %>% select_if(function(x) sum(x) > 1000), 
          mtcars %>% select(mpg, cyl))

#    disp  hp  mpg cyl
#1  160.0 110 21.0   6
#2  160.0 110 21.0   6
#3  108.0  93 22.8   4
#4  258.0 110 21.4   6
#5  360.0 175 18.7   8
#6  225.0 105 18.1   6
#7  360.0 245 14.3   8
#8  146.7  62 24.4   4
#....

但是,如果一列同时满足条件(在select_ifselect中被选中),则该列将重复出现。

我们也可以使用基本的R语言来实现相同的输出,但是使用unique避免了列被选择两次的问题。

sel_names <- c("mpg", "cyl")
mtcars[unique(c(sel_names, names(mtcars)[sapply(mtcars, sum) > 1000]))]

因此,对于您的情况,这两个版本将是:
bind_cols(df_inh %>% select_if(function(x) sd(x) != 0), 
          df_inh %>% select(isolate, Phenotype))

并且
sel_names <- c("isolate", "Phenotype")
df_inh[unique(c(sel_names, names(df_inh)[sapply(df_inh, sd) != 0]))]

3

我不会在这个任务中使用tidyverse函数。

df_new <- df_inh[,c(grep("isolate", names(df_inh)), 
                    grep("Phenotype", names(df_inh), 
                    which(sapply(df_inh, sd) != 0))]

上面的代码中,你只需使用grepwhich来按照每个条件进行索引,并用[]进行索引。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接