根据特定列值对R中的数据进行分组

时间:2017-03-28 14:50:39

标签: r

我在csv文件中有一组数据,我需要根据一列的转换进行分组。我是R的新手,我无法找到正确的方法来实现这一目标。

简化版数据:

Time    Phase    Pressure    Speed
 1        0        0.015      0
 2       25        0.015      0
 3       25        0.234      0
 4       25        0.111      0
 5        0        0.567      0
 6        0        0.876      0
 7       75        0.234      0
 8       75        0.542      0
 9       75        0.543      0

阶段改变状态的时间长度比上面的长,但我缩短了所有内容以使其可读,并且这种模式继续不断。我想要做的是计算相位非零的每个实例的压力和速度的平均值。例如,在上面样本的输出中,将有两条线,一条线具有相位为25的三条线的平均值,并且当相位为75时具有三条线的平均值。可以看到这样的情况:相位的相同数值显示不止一次,我需要分别处理每一个。也就是说,在阶段为0, 0, 25, 25, 25, 0, 0, 0, 25, 25, 0的情况下,我需要将第一组和第二组25s记录为单独的事件,以及任何其他非零组。

我尝试了什么:

`csv <- read.csv("c:\\test.csv")`
`ins <- subset(csv,csv$Phase == 25)`
`exs <- subset(csv,csv$Phase == 75)`
`mean(ins$Pressure)`
`mean(exs$Pressure)`

当相位为25和75时,这显然会返回整个文件的平均值,但是我需要以某种方式使用尾随和前导0将它分成组。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

超快:

df <- read.csv("your_file_name.csv")

cbind(aggregate(Pressure ~ Phase, df[df$Phase != 0,], FUN = mean),
      aggregate(Speed ~ Phase, df[df$Phase != 0,], FUN = mean)[2])

cbind很有意思 - 根据相位值的分布情况,您需要merge代替。

答案 1 :(得分:0)

编辑:根据提问者的反馈,他们真正寻求在数字运行中进行一些聚合(即第一组连续25秒,然后是第二组连续25秒,依此类推)。因此,我建议使用rle或运行级编码函数来获取可在aggregate命令中使用的组号。

我修改了原始数据,因此它包含两次25次运行,仅用于说明目的,但无论如何都应该有效。使用rle我们获得编码的数据运行,然后我们为每一行创建一个组号。我们通过获取观察到的长度总数的向量,然后使用rep函数以适当的长度重复每个长度来完成此操作。

完成此操作后,我们可以再次使用相同的基本聚合命令。

df_example <- data.frame(Time = 1:9,
                         Phase = c(0,25,25,25,0,0,25,25,0),
                         Pressure = c(0.015,0.015,0.234,0.111,0.567,0.876,0.234,0.542,0.543),
                         Speed = rep(x = 0,times = 9))

encoded_runs <- rle(x = df_example$Phase)
df_example$Group_No <- rep(x = 1:length(x = encoded_runs$lengths),
                           times = encoded_runs$lengths)

aggregate(x = df_example[df_example$Phase != 0,c("Pressure","Speed")],
          by = list(Group_No = df_example[df_example$Phase != 0,"Group_No"],
                    Phase = df_example[df_example$Phase != 0,"Phase"]),
          FUN = mean)

  Group_No Phase Pressure Speed
1        2    25    0.120     0
2        4    25    0.388     0

答案 2 :(得分:0)

根据Solos的评论和Cheesman的回答, 尝试:

csv$block = paste(csv$Phase, cumsum(c(1, diff(csv$Phase) != 0)))

df_example = csv

aggregate(x = df_example[df_example$Phase != 0,c("Pressure","Speed")],
        by = list(Phase = df_example[df_example$Phase != 0,"block"]),
        FUN = mean)

实际上plyr会很方便:

csv$block = paste(csv$Phase, cumsum(c(1, diff(csv$Phase) != 0)))

require(plyr)

ddply(csv[csv$Phase!=0,], .(block), summarize,
mean.Pressure=mean(Pressure), mean.Speed=mean(Speed))