R:基于同一数据帧中另一个因子的NROW为数据帧子集设置子集

时间:2018-09-21 12:51:15

标签: r dplyr

我在两个位置(参考mast6和sonic_f)的三个位置(u,v和w)有针对特定风角度(例如0º,5º等)的三个方向(u,v和w)的风速读数,我已导入并绑定所有这些都放在一个单一的data.frame中。

我想以成对形式绘制数据,但是参考桅杆在最初的X秒钟内没有记录。我需要将声音文件修整为第一个时间戳,每个角度和每个u v或w方向的等效参考杆数据都会显示出来。

例如,每个位置的开始时间如下:

> aggregate(data=df,StartTime~MeasurementLocation+Angle,min)
         Location Angle StartTime
1     mast6_u      00    17602
2     mast6_v      00    17602
3     mast6_w      00    18602
4   sonic_f_u      00        2
5   sonic_f_v      00        2
6   sonic_f_w      00        2
7     mast6_u      05    13001
8     mast6_v      05    13001
9     mast6_w      05    13002
10  sonic_f_u      05        2
11  sonic_f_v      05        2
12  sonic_f_w      05        2

因此,例如,属于角度00的所有数据的开始时间必须为18602。 编辑

所需的输出将是每个角度的单独文件,对于Angle == 00,sonic_f_u v或w的长度与对于相同角度的mast_u v或w的最短数据集的长度相同。例如。对于角度00,mast6_u v和w必须都从18602开始,因此sonic_f_u v和w也应从18602开始。

3 个答案:

答案 0 :(得分:4)

很难在此击败数据表...

library(data.table)
setDT(df)[ , start_time_max := max( StartTime ), by = Angle][StartTime >= start_time_max, ][, start_time_max := NULL][]

#    Num Location Angle StartTime
# 1:   3  mast6_w     0     18602
# 2:   9  mast6_w     5     13002

基准

microbenchmark::microbenchmark(
  data.table = setDT(df)[ , start_time_max := max( StartTime ), by = Angle][StartTime >= start_time_max, ][, start_time_max := NULL][],
  tidyverse = { left_join(df,
                          df %>%
                            group_by(Angle) %>%
                            summarise(max(StartTime)),
                          by = "Angle"
  ) %>%
      filter(StartTime == `max(StartTime)`) %>%
      select(-`max(StartTime)`) %>%
      arrange(Angle, Location) %>%
      unique()

    }, times = 100
)

# Unit: microseconds
#       expr      min       lq     mean   median       uq       max neval
# data.table  937.233 1050.057 1195.317 1196.169 1289.260  1808.488   100
# tidyverse  4694.900 4991.645 5409.146 5172.855 5341.563 24359.309   100

答案 1 :(得分:2)

我认为我不完全理解您的用例,但这就是我的解释方式:对于每个角度,您都希望找到最大开始时间,并针对桅杆和声波的所有风向对数据框进行过滤,以便具有相同的开始时间。

在tidyverse中,您可以通过找到每个角度的最大开始时间并将其加入原始数据帧来实现。然后使用过滤器删除不匹配的开始时间:

left_join(df,
          df %>%
            group_by(Angle) %>%
            summarise(max(StartTime)),
          by = "Angle"
) %>%
  filter(StartTime == `max(StartTime)`) %>%
  select(-`max(StartTime)`) %>%
  arrange(Angle, Location) %>%
  unique()

# # A tibble: 2 x 4
#   Location Angle StartTime
#   <chr>    <int>     <int>
# 1 mast6_w      0     18602
# 2 mast6_w      5     13002

使用arrange()和列进行排序以删除重复的行,并使用unique()除去重复项(如果行列不相同,则可能需要更强大的功能。

答案 2 :(得分:1)

假设我有

> dat
     Num  Location Angle StartTime
1    1   mast6_u     0     17602
2    2   mast6_v     0     17602
3    3   mast6_w     0     18602
4    4 sonic_f_u     0         2
5    5 sonic_f_v     0         2
6    6 sonic_f_w     0         2
7    7   mast6_u     5     13001
8    8   mast6_v     5     13001
9    9   mast6_w     5     13002
10  10 sonic_f_u     5         2
11  11 sonic_f_v     5         2
12  12 sonic_f_w     5         2

要将所有0角转换为0的{​​{1}}处的值,您可以执行以下操作:

mast6_w

这会将所有for (angle in c(0,5)) { dat[which(dat$Angle==0),4] <- dat[which(dat$Location=="mast6_w" & dat$Angle==0),4] } 角度的第4列值设置为00处的值。然后,您最终得到:

mast6_w

对于其他人,这里的结构是:

> dat
   Num  Location Angle StartTime
1    1   mast6_u     0     18602
2    2   mast6_v     0     18602
3    3   mast6_w     0     18602
4    4 sonic_f_u     0     18602
5    5 sonic_f_v     0     18602
6    6 sonic_f_w     0     18602
7    7   mast6_u     5     13001
8    8   mast6_v     5     13001
9    9   mast6_w     5     13002
10  10 sonic_f_u     5         2
11  11 sonic_f_v     5         2
12  12 sonic_f_w     5         2