【问题标题】:Select only certain columns from the data frame in R仅从 R 中的数据框中选择某些列
【发布时间】:2017-08-22 13:04:25
【问题描述】:

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

数据框如下所示:

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 不应该包含具有后缀“_1”的列 他们的名字,但包含其余的列。对于 df9,不应包含具有“_1”、“_2”、... 到“_8”的列 例如 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 之类的列。 我想从 df 中删除“城市”列。

我写了以下代码:

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。

谁能帮我解决这个问题?

提前致谢!!

【问题讨论】:

  • @lok​​i,两个问题都不一样。谢谢。

标签: r lapply


【解决方案1】:

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

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 的列缺少后缀或&gt;= i。这与

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

【讨论】:

  • ,我还有一个问题,我需要根据城市名称删除 a.Boston、a.Hartford 等列。例如,如果城市值为波士顿,则删除 a.Boston 列,如果是 Hartford,则删除 a.Hartford 列。因为我的原始数据框包含许多城市值。
【解决方案2】:
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 中,我首先定义了一个匹配所需列的正则表达式模式。 IE。

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

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

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

【讨论】:

  • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 2021-07-28
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多