R从data.table中删除总和为0的列 - 仍然不起作用

时间:2018-05-17 02:01:38

标签: r dataframe data.table

这似乎是一个重复的问题,但也许我在这里遗漏了一些东西。

我一直试图从data.table中删除绝对值之和为0的列。

我搜索并在此网站上找到了许多声称有效的解决方案,事实上,当我复制/粘贴确切的代码时,它确实有效。但是,出于某种原因,我无法使用data.table复制它。

我做的几乎所有事情的结果都将我的data.table变成了一个列表。我甚至试图将我的data.table转换为data.frame来试试这些解决方案而没有运气。

来自here

SelectVar[, colSums(SelectVar != 0) > 0]

不起作用。

SelectVar[, !apply(SelectVar == 0, 2, all)]

也不起作用。

remove_zero_cols <- function(df) {
  rem_vec <- NULL
  for(i in 1:ncol(df)){
    this_sum <- summary(df[,i])
    zero_test <- length(which(this_sum == 0))
    if(zero_test == 6) {
      rem_vec[i] <- names(df)[i]
    }
  }
  features_to_remove <- rem_vec[!is.na(rem_vec)]
  rem_ind <- which(names(df) %in% features_to_remove)
  df <- df[,-rem_ind]
  return(df)
}

此功能也不起作用。

我检查了每个参数的类,它们都是数字或整数类型。我还检查了任何NA,但没有找到。

有什么建议吗?

4 个答案:

答案 0 :(得分:3)

如果您正在处理data.table,请将with = FALSE添加到您引用的第一个解决方案。

# Create example data frame
SelectVar <- read.table(text = "    a   b  c   d   e   f   g   h   i j k l ll m n o p  q   r
1 Dxa8 Dxa8 0 Dxa8 Dxa8 0 Dxa8 Dxa8 0 0 0 0  0 0 0 0 0 Dxc8 0
2 Dxb8 Dxc8 0 Dxe8 Dxi8 0 tneg tpos 0 0 0 0  0 0 0 0 0 Dxi8 0",
                        header = TRUE, stringsAsFactors = FALSE)

# Convert to a data.table
library(data.table)

setDT(SelectVar)

SelectVar[, colSums(SelectVar != 0) > 0, with = FALSE]
#       a    b    d    e    g    h    q
# 1: Dxa8 Dxa8 Dxa8 Dxa8 Dxa8 Dxa8 Dxc8
# 2: Dxb8 Dxc8 Dxe8 Dxi8 tneg tpos Dxi8

答案 1 :(得分:1)

这是一个整合的解决方案。您可以将data.table转换为tibble,然后从那里开始。

library(tidyverse)
df <- tibble(a = 1:5, b = -1:3, c = 0)

selection_criteria <- (colSums(abs(df)) != 0)
df[selection_criteria]

答案 2 :(得分:1)

OP要求仅删除绝对值总和为零的列。后来,他澄清说他希望删除data.table列,每行只包含0行

这可以通过使用any()函数

来实现
library(data.table)

#create sample data
n_rows <- 10L
n_cols <-  5L
DT <- data.table(id = 1:n)
dat_cols <- sprintf("dat%i", seq.int(n_cols))
for (j in seq.int(n_cols)) set(DT, NULL, dat_cols[j], 0L)
set.seed(1L)
DT[sample.int(n_rows, 0.1 * n_rows), (sample.int(n_cols, 0.5 * n_cols)) := 1L]
DT
    id dat1 dat2 dat3 dat4 dat5
 1:  1    0    0    0    0    0
 2:  2    0    1    1    0    0
 3:  3    0    0    0    0    0
 4:  4    0    0    0    0    0
 5:  5    0    0    0    0    0
 6:  6    0    0    0    0    0
 7:  7    0    0    0    0    0
 8:  8    0    0    0    0    0
 9:  9    0    0    0    0    0
10: 10    0    0    0    0    0
# find columns which are all zero using any()
dat_cols <- sprintf("dat%i", seq.int(n_cols))
zero_cols <- setDT(DT)[, lapply(.SD, function(x) !any(x)), 
                .SDcols = dat_cols]
# remove columns in place
DT[, (names(which(unlist(zero_cols)))) := NULL][]
    id dat2 dat3
 1:  1    0    0
 2:  2    1    1
 3:  3    0    0
 4:  4    0    0
 5:  5    0    0
 6:  6    0    0
 7:  7    0    0
 8:  8    0    0
 9:  9    0    0
10: 10    0    0

答案 3 :(得分:0)

之前:

library(tidy verse)
DT = as_tibble(list(x=c(1,0), y=c(0,0)))
DT

A tibble: 2 x 2
        x     y
      <dbl> <dbl>
  1     1     0
  2     0     0

使用:

DT1 = DT %>% select_if(any)
DT1

之后:

  tibble: 2 x 1
        x
      <dbl>
  1     1
  2     0