如何基于列名对数据框进行子集化?

5

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))

我只想根据这个变量中的向量名称对数据帧进行子集筛选:

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

所以,我的最终数据框应该长成这个样子:
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))

有什么想法吗?


1
解决方案是:df[,select] - A Gore
2
df[c("Server", "Date", "Host_CPU", "UsedMemPercent", select)]。或者你可以使用 df[, c("Server", "Date", "Host_CPU", "UsedMemPercent", select)]。或者 subset(select = c("Server", "Date", "Host_CPU", "UsedMemPercent", select))。请参阅 ?subset 以获取详细信息。或者 ?[ - Gregor Thomas
请注意,将额外的步骤用于修改从dput输出的内容,以便可以直接粘贴到R中,这是非常受欢迎的。因此,与其仅使用dput(your_data)的输出,如果您将其粘贴到表单your_data <- {insert the dput output here}中,那就太好了。 - Dason
@Gregor,我遇到了这个错误:在[.data.frame(data, c("Server", "Date", "Host_CPU", "UsedMemPercent", : 选择了未定义的列。 - user1471980
我在subset中错过了df,应该是subset(df, select = c("Server", "Date", "Host_CPU", "UsedMemPercent", select))。但其他代码都可以在你分享的数据上在新的R会话中运行。 - Gregor Thomas
显示剩余2条评论
3个回答

10
请重新查看索引。如果您在R中使用索引机制[,则可以主要使用三种类型的索引:
  • 逻辑向量:与列数相同的长度,TRUE表示选择该列
  • 数字向量:根据位置选择列
  • 字符向量:根据名称选择列

如果您对数据框使用索引机制,则可以以两种方式处理这些对象:

  • 作为列表,因为它们在内部是列表
  • 作为矩阵,因为它们在许多情况下模仿矩阵行为

iris数据框为例,比较您可以从数据框中选择列的多种方法。 如果您将其视为列表,则有以下两个选项:

如果您想要单个列以向量形式,请使用[[

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

如果您需要一个或多个列,并且需要返回数据框,请使用[

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

如果您将它视为矩阵,那么您需要执行与矩阵相同的操作。如果您没有指定任何行索引,这些命令实际上等同于上面使用的命令:


如果把它看作是一个矩阵,那么你只需要按照处理矩阵的方式来做就可以了。如果你没有指定任何行索引,那么这些命令实际上和上面使用的命令是等价的:
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")]

所以在您的情况下,您只需要:

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

关于子集的注意事项:子集功能可以使用,但仅应在交互式环境下使用。帮助页面上有一个警告声明:

这是一个方便的功能,旨在用于交互式使用。对于编程而言,最好使用标准的子集功能,例如 [,特别是参数子集的非标准评估可能会产生意想不到的后果。


2

将数据框保存到变量df中:

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)
  )

df[,select] 应该是你正在寻找的。


注:本文为 IT 技术相关内容。

@user1471980 如果您创建了select,那么这个答案完全有效。但是您没有指定您还想保留其他一些内容。 - Joris Meys
1
@user1471980 是的,我误解了你的问题,看起来你需要:cbind(df[,1:4], df[,select]) - Alex Braksator

1
这里有一种方法: df[,c(1:4,7:9)]
你也可以使用dplyr来选择列: select(df, Server,Date,Host_CPU,UsedMemPercent,jvm3,jvm4,jvm5)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接