Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do you subset a data frame based on column names?

Tags:

r

I have this data frame:

 dput(df)
structure(list(Server = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = "servera", class = "factor"), 
    Date = structure(1:6, .Label = c("7/13/2017 15:01", "7/13/2017 15:02", 
    "7/13/2017 15:03", "7/13/2017 15:04", "7/13/2017 15:05", 
    "7/13/2017 15:06"), class = "factor"), Host_CPU = c(1.812950134, 
    2.288070679, 1.563278198, 1.925239563, 5.350669861, 2.612503052
    ), UsedMemPercent = c(38.19, 38.19, 38.19, 38.19, 38.19, 
    38.22), jvm1 = c(10.91, 11.13, 11.34, 11.56, 11.77, 11.99
    ), jvm2 = c(11.47, 11.7, 11.91, 12.13, 12.35, 12.57), jvm3 = c(75.65, 
    76.88, 56.93, 58.99, 65.29, 67.97), jvm4 = c(39.43, 40.86, 
    42.27, 43.71, 45.09, 45.33), jvm5 = c(27.42, 29.63, 31.02, 
    32.37, 33.72, 37.71)), .Names = c("Server", "Date", "Host_CPU", 
"UsedMemPercent", "jvm1", "jvm2", "jvm3", "jvm4", "jvm5"), class = "data.frame", row.names = c(NA, 
-6L))

I only want to be able to subset this data frame based on the vectors names in this variable:

select<-c("jvm3", "jvm4", "jvm5")

so, my final df should look like this:

structure(list(Server = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = "servera", class = "factor"), 
    Date = structure(1:6, .Label = c("7/13/2017 15:01", "7/13/2017 15:02", 
    "7/13/2017 15:03", "7/13/2017 15:04", "7/13/2017 15:05", 
    "7/13/2017 15:06"), class = "factor"), Host_CPU = c(1.812950134, 
    2.288070679, 1.563278198, 1.925239563, 5.350669861, 2.612503052
    ), UsedMemPercent = c(38.19, 38.19, 38.19, 38.19, 38.19, 
    38.22), jvm3 = c(75.65, 76.88, 56.93, 58.99, 65.29, 67.97
    ), jvm4 = c(39.43, 40.86, 42.27, 43.71, 45.09, 45.33), jvm5 = c(27.42, 
    29.63, 31.02, 32.37, 33.72, 37.71)), .Names = c("Server", 
"Date", "Host_CPU", "UsedMemPercent", "jvm3", "jvm4", "jvm5"), class = "data.frame", row.names = c(NA, 
-6L))

any ideas?

like image 680
user1471980 Avatar asked Dec 14 '22 22:12

user1471980


1 Answers

Please revisit indices. If you use the index mechanism [ in R, you can use mainly three types of indices:

  • logical vectors: same length as the number of columns, TRUE means select the column
  • numeric vectors: selects columns based on position
  • character vectors: select columns based on name

If you use the index mechanism for data frames, you can treat these objects in two ways:

  • as a list, because they are internally lists
  • as a matrix, because they mimick matrix behaviour in many cases

Take the iris data frame as example to compare the multiple ways you can select columns from a data frame. If you treat it as a list, you have the following two options:

Use [[ if you want a single column in the form of a vector:

iris[["Species"]]
# [1] setosa     setosa     setosa ... : is a vector

Use [ if you want one or more columns, but you need a data frame back :

iris["Species"]
iris[c("Sepal.Width", "Species")]

If you treat it as a matrix, you just do the exact same as you would do with a matrix. If you don't specify any row indices, these commands are actually equivalent to the ones used above:

iris[ , "Species"] # is the same as iris[["Species"]]
iris[ , "Species", drop = FALSE] # is the same as iris["Species"]
iris[ , c("Sepal.Width", "Species")] # is the same as iris[c("Sepal.Width", "Species")]

So in your case, you simply need:

select <- c("Server","Date","Host_CPU","UsedMemPercent",
            "jvm3","jvm4","jvm5")
df[select]

Note on subset: subset works, but should ONLY be used interactively. There's a warning on the help page stating :

This is a convenience function intended for use interactively. For programming it is better to use the standard subsetting functions like [, and in particular the non-standard evaluation of argument subset can have unanticipated consequences.

like image 65
Joris Meys Avatar answered Jan 07 '23 05:01

Joris Meys