dplyr:根据数据创建列

时间:2016-01-11 19:22:05

标签: r

我有~150个逻辑变量,想要删除琐碎的变量(所有数据值都为FALSE)。我怎么能用dplyr做到这一点?

我正在做什么(也许我根本不需要它,仍在学习)。我有数据,每个数据点都被分类。诀窍在于同一点可能有多个类别,因此它不是一个因素:

y | x | domain
------------------
0 | 1 | dogs,animals
1 | 5 | cats,animals

我想为y建立一个预测模型。我将这个结构(在R之外)转换为逻辑列:

y | x | d_dogs | d_cats | d_animals
-----------------------------------
0 | 1 |    T   |    F   |    T
1 | 5 |    F   |    T   |    T

我正在建立一个回归模型。 (类别嵌套在自己身上,但这是另一个主题)。

但有些类别的数据点太少(全部,或几乎所有值都是F),所以我想删除它们。没有dplyr我做:

keep.columns <- sapply(colnames(data), function(n) {
    c <- data[,n];
    !is.logical(c) || sum(c) > 1
})
data[, keep.columns]

但我很好奇,如果我能做到这一点更容易。

3 个答案:

答案 0 :(得分:4)

我们可以使用Filter

 Filter(function(x) !is.logical(x) | sum(x)>1, data)

答案 1 :(得分:2)

你基本上做的是正确的事情,但可以进行一些简化:

data[ , !sapply(data, is.logical) | (colSums(data) > 1)]

让我展示它如何使用和示例数据集:

data <- data.frame(x = 1:6,
                   d_dogs = rep(FALSE, 6),
                   d_cats = rep(c(FALSE, TRUE), 3),
                   d_horses = rep(TRUE, 6),
                   d_animals = c(rep(FALSE, 5), TRUE))
data
##   x d_dogs d_cats d_horses d_animals
## 1 1  FALSE  FALSE     TRUE     FALSE
## 2 2  FALSE   TRUE     TRUE     FALSE
## 3 3  FALSE  FALSE     TRUE     FALSE
## 4 4  FALSE   TRUE     TRUE     FALSE
## 5 5  FALSE  FALSE     TRUE     FALSE
## 6 6  FALSE   TRUE     TRUE      TRUE

您可以使用它来获取不符合逻辑的列,而不是使用sapply来应用“复杂”函数,而不是:

!sapply(data, is.logical)
##     x    d_dogs    d_cats  d_horses d_animals 
##  TRUE     FALSE     FALSE     FALSE     FALSE 

要获得每列TRUE的数量,您可以使用colSums

colSums(data)
##         x    d_dogs    d_cats  d_horses d_animals 
##        21         0         3         6         1 

把所有东西放在一起:

data[ , !sapply(data, is.logical) | (colSums(data) > 1)]
##   d_cats d_horses
## 1  FALSE     TRUE
## 2   TRUE     TRUE
## 3  FALSE     TRUE
## 4   TRUE     TRUE
## 5  FALSE     TRUE
## 6   TRUE     TRUE

您可以使用dplyr,但我不认为它确实提供了简化。这可行:

select(data, which(!sapply(data, is.logical) | (colSums(data) > 1)))

答案 2 :(得分:1)

要查找具有普通(相同)值的列,您可以尝试:

df <- data.frame(a = c(1,1,1,1,1), b = c(1,2,3,4,5), c = c("a","a","a","a","a"))

df %>% 
summarise_each(funs(n_distinct))

输出:

  a b c
1 1 5 1

即,cols“a”和“c”只有1个唯一/不同的值