根据因素水平使用列名删除列

Remove columns using column name based on levels of factors

我有一个数据框,其中包含一列因素和包含每个因素值的列以及不再包含在数据框中的其他因素。示例:

x <- data.frame(f= toupper(sample(letters[1:3], 5, replace=T)), 
            x.A = seq(1:5),
            x.B = seq(1:5),
            x.C = seq(1:5),
            x.D = seq(1:5),
            x.E = seq(1:5))

导致:

  f x.A x.B x.C x.D x.E
1 B   1   1   1   1   1
2 B   2   2   2   2   2
3 A   3   3   3   3   3
4 C   4   4   4   4   4
5 A   5   5   5   5   5

现在我想删除 f 列中所有不代表当前水平的列,从而得到一个数据框:

  f x.A x.B x.C
1 B   1   1   1
2 B   2   2   2
3 A   3   3   3
4 C   4   4   4
5 A   5   5   5

级别和列名称的命名约定是一致的,名称始终采用 somevariable.FACTORLEVEL 的形式。我会在列表中键入所有名称以供选择,但它变得又长又笨重。我尝试使用 grep 如下:

subX <- x[x$f == 'B', grep('B', names(x))]

但不太明白我想要什么,也不知道如何在所有级别上扩展它(如果它确实有效)。我也查看了以前的问题 here and here,但它们没有达到我需要的程度。任何帮助,将不胜感激。谢谢。

我们使用sub去掉'x'的列名前缀x.,检查是否是%in%创建的'f'列逻辑 vector 并使用它来对 'x' 的列进行子集化。我们删除了第一列名称(因为它是 'f'),然后与 TRUE 连接以将该列也包含在子集中。

 x[c(TRUE,sub('.*\.', '', names(x)[-1]) %in% x$f)]

或者我们可以将 greplpattern 一起使用 paste 将 'f' 列指定为 return 逻辑索引。

x[c(TRUE,grepl(paste(x$f, collapse='|'), names(x)[-1]))]

这也行。

x[c(T, (gsub("x.", "", names(x)) %in% x$f)[-1])]