从R中的数据框中仅选择某些列

时间:2017-08-22 13:04:25

标签: r lapply

我是R的新手。我有一个下面的数据框,我需要从中选择特定的列。

Dataframe如下所示:

df<-data.frame(city=as.character("Boston","Boston","Boston","Boston","Boston","Boston","Boston","Boston","Boston","Boston"),
              a.Boston=c(rep(8,3),rep(6,4),9,5,7),
              a.Hartford=c(rep(6,3),rep(2,4),1,5,0),
              a.Denver=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_0=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_1=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_2=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_3=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_4=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_5=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_6=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_7=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_8=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_9=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_10=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_11=c(rep(8,3),rep(9,4),3,8,9),
              b.Boston_12=c(rep(8,3),rep(9,4),3,8,9),
              b.Denver_0=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_1=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_2=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_3=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_4=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_5=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_6=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_7=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_8=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_9=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_10=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_11=c(rep(6,3),rep(2,4),1,5,0),
              b.Denver_12=c(rep(6,3),rep(2,4),1,5,0))

我想根据列的选择创建数据帧df1到df12。例如,df2不应包含具有后缀&#34; _1&#34;的列。在 他们的名字,但包含其余的列。对于df9,不应包含具有&#34; _1&#34;,&#34; _2&#34;,... upto&#34; _8&#34; 例如b.Boston_1,b.Denver_1,b.Boston_2,b.Denver_2 ..... b.Boston_8,b.Denver_8但包含诸如 b.Boston_10,b.Denver_10,b.Boston_11,b.Denver_11。 df12只包含a.Boston,a.Hartford,a.Denver等列。 我想删除&#34; city&#34;来自df&#39的专栏。

我写了以下代码:

i1 <- 0:12
for(i in seq_along(i1)) {
  assign(paste0("df", i),
         value = df[, setdiff(names(df),
                                  c("city", 
                                    grep(paste("_", 0:i1[i],collapse="|", sep=""),
                                         colnames(df), value = TRUE)))])
}

下面我得到了结果:

*df2*

      a.Boston a.Hartford a.Denver b.Boston_2 b.Boston_3 b.Boston_4 b.Boston_5 b.Boston_6 b.Boston_7 b.Boston_8
1        8          6        8          8          8          8          8          8          8          8
2        8          6        8          8          8          8          8          8          8          8
  b.Boston_9 b.Denver_2 b.Denver_3 b.Denver_4 b.Denver_5 b.Denver_6 b.Denver_7 b.Denver_8 b.Denver_9
1          8          6          6          6          6          6          6          6          6
2          8          6          6          6          6          6          6          6          6

DF9

 a.Boston a.Hartford a.Denver b.Boston_9 b.Denver_9
1        8          6        8          8          6
2        8          6        8          8          6

问题,对于创建的数据帧,例如df2和df9,它们不包含从b.Denver_10到b.Denver_12的列 和b.Boston_10到b.Boston_12。 df1到df11的数据帧都没有包含后缀_10,_11,_12的列,但它应该在那里。

所需的o / p:

DF9

a.Boston a.Hartford a.Denver b.Boston_9 b.Boston_10 b.Boston_11 b.Boston_12 b.Denver_9 b.Denver_10
1        8          6        8          8           8           8           8          6           6
2        8          6        8          8           8           8           8          6           6
  b.Denver_11 b.Denver_12
1           6           6
2           6           6

DF10

a.Boston a.Hartford a.Denver b.Boston_10 b.Boston_11 b.Boston_12 b.Denver_10 b.Denver_11 b.Denver_12
1        8          6        8           8           8           8           6           6           6
2        8          6        8           8           8           8           6           6           6

这种类型的o / p,我想从df1到df12。

任何人都可以帮我解决这个问题吗?

提前感谢!!

2 个答案:

答案 0 :(得分:0)

lapply(1:12, function(k)
{
    # match numbers equal or greater than k in colnames of df
    pattern <- if (k < 10) paste0("\\..*\\D$|_([",k,"-9]|1[0-2])$") else 
        paste0("\\..*\\D$|_(1[",k%%10,"-2])$")
    df[,grepl(pattern, colnames(df))]
})

编辑:在lapply内,我首先定义一个匹配所需列的正则表达式patern。即

A)包含'。'的列并且不包含数字后跟行尾。 (\\..*\\D$)这与格式为a.CityName

的列匹配

B)包含“_”后跟数字等于或大于给定k且不大于12的列。该公式取决于k <10。例如。对于k = 2,我们得到_([2-9]|1[0-2])$ - 匹配2到9或1,然后是0到2.对于k = 11,我们得到_(1[1-2])$

然后我选择与grepl匹配模式的列。

答案 1 :(得分:0)

如果我们为所需的列指定条件而不是构造正则表达式,则代码会更加清晰。

library(dplyr)
library(stringr)

column_suffixes <- str_extract(names(df), '\\d+') %>%
    as.integer

lapply(seq_len(12), function(i) {
    df %>%
        select_if(is.na(column_suffixes) | column_suffixes >= i) %>%
        select(-city)
})

column_suffixes只是列名中的向量整数。如果没有整数,则为NA

select_if只会设置缺少后缀的df列或>= i。这与

具有相同的效果
df[, is.na(column_suffixes) | column_suffixes >= i]