从数据框中提取特定列

Are*_*bre 345 r dataframe

我有一个包含6列的R数据框,我想创建一个只有三列的新数据框.

假设我的数据帧df,并且我想提取列A,BE,这是唯一的命令,我可以计算出:

 data.frame(df$A,df$B,df$E)
Run Code Online (Sandbox Code Playgroud)

有更紧凑的方式吗?

Jos*_*ich 432

您可以使用列名称向量进行子集化.我强烈建议使用这种方法,而不是将列名称视为对象名称(例如subset()),尤其是在函数,包或应用程序中进行编程时.

# data for reproducible example
# (and to avoid confusion from trying to subset `stats::df`)
df <- setNames(data.frame(as.list(1:5)), LETTERS[1:5])
# subset
df[,c("A","B","E")]
Run Code Online (Sandbox Code Playgroud)

  • @ArenCambre:那你的data.frame并没有真正命名为`df`.`df`也是stats包中的一个函数. (24认同)
  • 这种语法存在一个问题,因为如果我们只提取一列R,则返回一个向量而不是数据帧,这可能是不需要的:`> df [,c("A")]``[1] 1`.使用`subset`没有这个缺点. (7认同)
  • @ArenCambre:http://2.bp.blogspot.com/-XU9PduVhq-I/Um-Y6e19jZI/AAAAAAAADfI/PrmoFQexa5M/s1600/Book+last+page.jpg (5认同)
  • 这给出了错误`类型'对象'的对象'不是子表化的. (4认同)
  • @Cina:因为` - "A"`是语法错误.并且`?Extract`说,"`i`,`j`,`...`也可以是负整数,表示元素/切片不在选择范围内." (2认同)

Sam*_*rke 128

使用dplyr包,如果调用了data.frame df1:

library(dplyr)

df1 %>%
  select(A, B, E)
Run Code Online (Sandbox Code Playgroud)

这也可以在没有%>%管道的情况下编写:

select(df1, A, B, E)
Run Code Online (Sandbox Code Playgroud)

  • 鉴于tidyverse的变化率很高,我谨告您不要使用这种模式。这是我强烈反对在为函数,程序包或应用程序编写代码时将列名视为对象名称的强烈偏爱。 (4认同)
  • 这是一个有用的解决方案,但对于问题中给出的示例,乔什的答案更具可读性、更快且无依赖性。我希望新用户在进入 tidyverse 之前先学习方括号子集设置:)! (3认同)
  • 自发布我的问题以来,Tidyverse有了长足的发展,我将答案转给了您。 (2认同)
  • 提交这个答案已经四年多了,格局没有变。管道表达式可以非常直观,这就是它们吸引人的原因。 (2认同)

Sté*_*ent 96

这是该subset()功能的作用:

> dat <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> subset(dat, select=c("A", "B"))
  A B
1 1 3
2 2 4
Run Code Online (Sandbox Code Playgroud)


Hen*_*nry 75

有两个明显的选择:Joshua Ulrich df[,c("A","B","E")]或者

df[,c(1,2,5)]
Run Code Online (Sandbox Code Playgroud)

如在

> df <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> df
  A B C D E F
1 1 3 5 7 8 9
2 2 4 6 7 8 9
> df[,c(1,2,5)]
  A B E
1 1 3 8
2 2 4 8
> df[,c("A","B","E")]
  A B E
1 1 3 8
2 2 4 8
Run Code Online (Sandbox Code Playgroud)


Ama*_*man 14

您还可以使用sqldf在R数据帧上执行选择的包:

df1 <- sqldf("select A, B, E from df")
Run Code Online (Sandbox Code Playgroud)

这给出了一个df1带有列的数据帧:A,B,E.


Ric*_*all 12

再次使用dplyr,其中df1是您的原始数据框:

df2 <- subset(df1, select = c(1, 2, 5))
Run Code Online (Sandbox Code Playgroud)

  • 这不使用`dplyr`.它使用`base :: subset`,与[Stephane Laurent的答案](/sf/answers/706054611/)相同,只是您使用列号而不是列名. (6认同)

so8*_*860 11

仅出于某种原因

df[, (names(df) %in% c("A","B","E"))]
Run Code Online (Sandbox Code Playgroud)

为我工作.所有上述语法都产生了"未定义的列选择".


Moo*_*per 5

您可以使用with

with(df, data.frame(A, B, E))
Run Code Online (Sandbox Code Playgroud)