删除多列等于确切数字R

时间:2018-07-16 20:15:41

标签: r data.table

我想对x1和x2 == 9的行进行子集化。我的真实集合有200多个列,其中列名以相同的字符串开头。下面的虚拟代码创建了一个较小的数据样本。如果可能的话,我希望使用R data.table软件包来实现此目的。

df <- data.frame('id'=c(1,2,3), 'x1'=c(9,9,4), 'x2'=c(9,9,4))
head(df)

# does not work, but thought perhaps I could have defined the columns via a paste and then subset where columns were equal to 9.
df[which(paste0("x", 1:2)==9), ]

更新:对不起,如果我不清楚。我知道只是为x1x2添加了一个过滤器。问题是实际数据由200多个列组成:x1:x200。我正在寻找比以下建议更清洁的解决方案。

7 个答案:

答案 0 :(得分:3)

如果您想要一个有效的基础R解决方案,则只需使用rowSums,例如

cols <- paste0("x", 1:2) 
df[rowSums(df[cols] == 9) == length(cols), ]
#   id x1 x2
# 1  1  9  9
# 2  2  9  9

如果您想要一个data.table解决方案,我将使用二进制连接,例如

library(data.table)
setDT(df)[as.list(rep(9, length(cols))), on = cols]
#    id x1 x2
# 1:  1  9  9
# 2:  2  9  9

数据

df <- data.frame(id = 1:3, x1 = c(9, 9, 4), x2 = c(9, 9, 4))

答案 1 :(得分:2)

也许是这样?

df[apply(df[, paste0("x", 1:200)] == 9, 1, all), ]

答案 2 :(得分:2)

融化可以使您不必写出每一列(对于> 2列的情况):

> aTbl = as.data.table(df)

> aTbl[, all9sP := F]
> aTbl[, .SD
       ][, !'all9sP'
       ][, melt(.SD, id.vars=c('id'))
       ][, NVars := uniqueN(variable)
       ][value == 9
       ][, .(N9s=.N), .(id, NVars)
       ][, all9sP := N9s == NVars
       ][, aTbl[.SD, all9sP := i.all9sP, on=.(id)]
       ][all9sP == T
       ][, all9sP := NULL
       ][, .SD
       ]

   id x1 x2
1:  1  9  9
2:  2  9  9
> 

答案 3 :(得分:1)

尝试:

for (i in 2:200) {df = df[df[,i] == 9,]}

编辑(被误解了,现在应该可以解决问题了):

{{1}}

答案 4 :(得分:1)

您也可以将grepapply一起使用

# Select all columns that have (colnames) "x"  
col.names <- grep("x",colnames(df), value = TRUE)
# Select rows where row == 9
sel <- apply(df[,col.names], 1, function(row) 9 %in% row)
df[sel,]

和输出

  id x1 x2
1  1  9  9
2  2  9  9

答案 5 :(得分:1)

使用data.table解决方案

创建数据集

ncols <- 5
cnms <- paste0("x", 1:ncols)
X <- data.table(ID = 1:1e6)
X[, (cnms) := NA_integer_]
X[, (cnms) := lapply(X = 1:ncols, sample, size = .N, x = 1:10)]

查找总和等于9的行

X1 <- X[, s := rowSums(.SD), .SDcols = cnms][s == 9, ][, s:= NULL][]
X1

查找所有列均等于9的行

X[, s := NULL]
ind <- rowSums(X[, lapply(.SD, is.element, set = 9), .SDcols = cnms])
X2 <- X[ind == length(cnms)][]
X2

修改 这实际上要快得多:

X[, s := NULL]
ind <- rowSums(X[, .SD , .SDcols = cnms] == 9)
X2 <- X[ind == length(cnms)][]
X2

Edit2 请参阅https://stackoverflow.com/users/3001626/david-arenburg中的答案。快很多。

答案 6 :(得分:0)

在提要中,尝试rowwise并照常使用filter

df %>% 
  rowwise() %>% 
  filter(x1 %in% 9 & x2 %in% 9 )

Source: local data frame [2 x 3]
Groups: <by row>

# A tibble: 2 x 3
     id    x1    x2
  <dbl> <dbl> <dbl>
1     1     9     9
2     2     9     9