使用dplyr在条件下选择/删除列(筛选列)R

3
有没有一种使用的方法,根据某些条件过滤列?这有点令人困惑,因为它与正常筛选相反。
我在SO上没有找到直接适用的内容。找到了这个这个但它们做的不完全相同。
基本上,我想根据行的值删除列,而不是根据列的值过滤行。
以下示例使用以下数据框:
df <- data.frame(aa = c("1", "a", "10.2", "12.1", "8.7"), 
                 ab = c("1", "b", "5.3", "8.1", "9.2"), 
                 ac = c("0", "a", "1.8", "21.5", "16.0"), 
                 ad = c("0", "b", "11.1", "15.9", "23.6"))

我知道这是一组奇怪的数据,而且列中包含不同类型的数据。这正是提出问题的原因,我正在尝试清理它们。
以下是传统子集方法的base解决方案,返回列"ab"和"ad":
df[, df[2,] == "b"]

有没有一种使用dplyr来完成这个任务的方法?我尝试使用filterselectsubset都无法实现,但可能我在这种情况下使用它们不正确。


@GeorgeWood 检查了链接。它没有涉及使用条件语句。我可以手动选择,但我想让 R 帮我完成这个任务。 - hmhensen
基本R解决方案有什么问题吗? - tjebo
我建议尝试为问题寻找更好的标题,以便于搜索引擎更好地显示。例如:选择包含行内字符串的列。"Filter"有点保留用于过滤行。最好避免使用'df'和类似的缩写,因为这些是baseR函数,你会干扰其他人的环境。 - tjebo
1
@Tjebo,我已经更改了标题以反映您的关注点。但是,我保留了“filter”的参考。虽然这个问题可能不是关于过滤的,但我认为这个概念是相似的,因此人们可能会使用这个术语搜索这个解决方案。 - hmhensen
2个回答

7
您可以使用 select_if,它是 select 的作用域变体。
df %>%
  select_if(function(x) any(x == "b"))

#    ab   ad
# 1   1    0
# 2   b    b
# 3 5.3 11.1
# 4 8.1 15.9
# 5 9.2 23.6

这里提供了一个函数,用于查找包含“b”的任何列。
根据您下面的评论进行编辑:
df %>%
  mutate(row_n = 1:n()) %>%
  select_if(function(x) any(x == "b" & .$row_n == 2))

这里,我们修改了一个名为n_row的变量,表示行号,然后将行号作为条件添加到调用select_if中。


这是正确的方向,但我需要它查看第二行,因为我的数据集中会有其他行包含相同的值。 - hmhensen
编辑了答案以添加行号的进一步条件。 - George Wood
不错的解决方案。运行得很好。我进行了一些微调,我认为这样更简单明了。我用 rownames 替换了 row_n,以避免使用 mutatedf %>% select_if(function(x) any(x == "b" & rownames(df) == 2))。当然,然后我们必须再次调用 df,所以这是一个偏好问题。也可以在最后用 mutate(row_n = NULL) 将新列 row_n 变异出来。 - hmhensen

3
您可以使用以下方法:
 df <- df %>%
    select(ab, ad)

使用这种方式的好处在于,你还可以不使用以下想法进行选择:
 df <- df %>%
    select(-ab) 

这将选择所有列,但不包括"ab"。 希望这正是您所寻找的。

谢谢您的尝试,但这并没有回答问题,因为没有应用条件。 - hmhensen
你可以在select中使用更多的内容。例如:select(contains("a"))更多信息请查看这里: https://www.r-bloggers.com/the-complete-catalog-of-argument-variations-of-select-in-dplyr/ - gabzo

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