1

我有一个示例数据框:

a <- c(1:6)
b <- c("05/12/2012 05:00","05/12/2012 06:00","06/12/2012 05:00",
   "06/12/2012 06:00", "07/12/2012 09:00","07/12/2012 07:00")
c <-c("0","0","0","1","1","1")
df1 <- data.frame(a,b,c,stringsAsFactors = FALSE)

首先,我想确保 R 识别日期和时间格式,所以我使用了:

df1$b <- strptime(df1$b, "%d/%m/%Y %H:%M")

然而,这不可能是正确的,因为 R 总是在我尝试查看新数据帧时中止我的会话。

假设这得到解决,我想根据数据框中包含“C”中不为零的最多数据的任何一天来获取数据的子集。在上面的例子中,我应该在 2012 年 12 月 7 日留下两个数据点。

我还有一个额外的相关问题。
如果我想在一天中的某个时间段(比如 07:00 和 08:00 之间)留下具有最​​多非零值的数据子集,我将如何去做?

对上述问题的任何帮助将不胜感激。

4

2 回答 2

2

同意杰克。听起来像是 R 的损坏安装。首先要尝试的是删除.Rdata保存前一个会话结果的文件。它们在 Mac 和 Windows 中都是隐藏的,因此除非您“显示”“点文件”(系统文件),否则操作系统文件管理器(Finder.app 和 Windows 资源管理器)将不会显示它们。如何查找和删除该文件是特定于操作系统的任务。它将在您的工作目录中,您需要在 R 之外进行删除,因为一旦 R 启动,它将锁定对它的访问。也有可能获得损坏的.history文件,但根据我的经验,这通常不是问题的根源。

如果这不成功,您可能需要重新安装 R。

于 2013-02-06T18:08:47.450 回答
2

好吧,好消息是我有一个答案给你,坏消息是你有更多的问题要问自己。首先是坏消息:您需要考虑如何处理具有相同数量的“c”非零值的多天。我不会在这个答案中解决这个问题。

现在好消息:这真的很简单。

第 1 步:首先,让我们重新格式化您的数据框。由于我们要更改几个变量的数据类型(b 为日期时间,c 为数字),我们需要创建一个新的数据框或重新校准旧的数据框。我更喜欢保留原件并创建一个新的,如下所示:

a <- df1$a
b <- strptime(df1$b, "%d/%m/%Y %H:%M")
c <- as.numeric(df1$c)
hour <- as.numeric(format(b, "%H"))
date <- format(b, "%x")

df2 <- data.frame(a, b, c, hour, date)

#   a                   b c hour      date
# 1 1 2012-12-05 05:00:00 0    5 12/5/2012
# 2 2 2012-12-05 06:00:00 0    6 12/5/2012
# 3 3 2012-12-06 05:00:00 0    5 12/6/2012
# 4 4 2012-12-06 06:00:00 1    6 12/6/2012
# 5 5 2012-12-07 09:00:00 1    9 12/7/2012
# 6 6 2012-12-07 07:00:00 1    7 12/7/2012

请注意,我还添加了“小时”和“日期”变量。这是为了使我们的数据易于按这些字段排序,以供我们以后的聚合功能使用。

第 2 步:现在,让我们计算每天 06:00 到 08:00 之间有多少个非零值。由于我们使用的是“小时”值,这意味着“6”和“7”的值(代表 06:00 - 07:59)。

library(plyr)
df2 <- ddply(df2[df2$hour %in% 6:7,], .(date), mutate, non_zero=sum(c))

#   a                   b c hour      date non_zero
# 1 2 2012-12-05 06:00:00 0    6 12/5/2012        0
# 2 4 2012-12-06 06:00:00 1    6 12/6/2012        1
# 3 6 2012-12-07 07:00:00 1    7 12/7/2012        1

'plyr' 包非常适合这样的事情。“ddply”包专门将数据帧作为输入和输出(因此称为“dd”),而“mutate”函数允许我们在添加额外列的同时保留所有数据。在这种情况下,我们想要 'c' 中的每一天的总和.(date)。在 data 参数中按小时对我们的数据进行子集处理df2[df2$hour %in% 6:7,],它表示向我们显示小时值在集合 {6,7} 中的行。

第 3 步:最后一步是按非零值的最大数量对数据进行子集化。我们可以删除我们使用的额外列并回到我们原来的三列。

subset_df <- df2[df2$non_zero==max(df2$non_zero),1:3]

#   a                   b c
# 2 4 2012-12-06 06:00:00 1
# 3 6 2012-12-07 07:00:00 1

祝你好运!

更新:应 OP 的要求,我正在编写一个新的“ddply”函数,该函数还将包含一个用于绘图的时间列。

df2 <- ddply(df2[df2$hour %in% 6:7,], .(date), mutate, non_zero=sum(c), plot_time=as.numeric(format(b, "%H")) + as.numeric(format(b, "%M")) / 60)
subset_df <- df2[df2$non_zero==max(df2$non_zero),c("a","b","c","plot_time")]

我们需要将时间分解为一个连续变量,所以我选择了小时。以时间格式保留任何数据将需要我们稍后处理一些东西,并且使用字符串格式(如“hh:mm”)将限制您可以在其上使用的函数类型。连续数字是最灵活的,所以这里我们得到小时数as.numeric(format(b, "%H"))并将其添加到分钟数除以 60as.numeric(format(b, "%M")) / 60以将分钟转换为小时单位。另外,由于我们要处理更多的列,我已经切换了最后的子集语句来命名我们想要的列,而不是引用数字。一旦我处理了非连续顺序的列,我发现使用名称更容易调试。

于 2013-02-07T02:51:00.250 回答