R合并数据框中的行

Ror*_*haw 5 r dataframe

这是head一个大数据框的

head(Hdata_soil)
                      X_id           timestamp address rssi batt_v soil_temp_1 soil_temp_2 soil_temp_3 soil_moisture_1
1 565846060dd8e408e3817c58 2015-11-27 12:01:10      A8  -65     NA          NA          NA          NA              NA
2 565846070dd8e408e3817c59 2015-11-27 12:01:11      A8   NA     NA        9.73     -273.15       14.63             647
3 565846cf0dd8e408e3817caf 2015-11-27 12:04:31      A7  -64     NA          NA          NA          NA              NA
4 565846cf0dd8e408e3817cb0 2015-11-27 12:04:31      A7   NA     NA        8.56        9.46        9.64             660
5 565847650dd8e408e3817cf5 2015-11-27 12:07:01      A8  -64     NA          NA          NA          NA              NA
6 565847660dd8e408e3817cf6 2015-11-27 12:07:02      A8   NA     NA        9.82     -273.15       14.29             643
Run Code Online (Sandbox Code Playgroud)

可以从dropbox访问完整的数据集

正如你可以看到有每个连续的2个观察值addresstimestamps大约1秒间隔。变量在这 2 个观察值之间拆分。我怎样才能将它们合并成一行,保留第一行timestamp

确保这仅发生在来自同一个address.

如果有人能就要使用的包/功能向我指出正确的方向,我将不胜感激。

fde*_*sch 0

查看下面的代码应该可以满足您的需求。首先,时间戳列被转换为“POSIXlt”类的对象,它允许确定单个观察之间的时间差。然后,我使用foreach并行循环所有行,并跳过在上一次迭代期间已合并到另一个中的所有记录(保存在向量“used”中)。which与 结合difftime可以识别连续的观察结果(例如,距当前处理的观察结果 5 秒内)。最后(并且仅当当前观察的“地址”存在于候选记录中时),行才会被合并,用连续观察中的值替换当前处理的行中的缺失值。

## load 'foreach' package
library(foreach)

## import and reformat data
Hdata_soil <- read.csv("Hdata_soil.csv", header = TRUE, 
                       stringsAsFactors = FALSE)

## reformat timestamps
timestamps <- strptime(Hdata_soil$timestamp, format = "%Y-%m-%d %H:%M:%S")

## vector with information about merged lines
used <- integer()
dat_out <- foreach(i = 1:length(timestamps), .combine = "rbind") %do% {

  ## skip current iteration if line has already been merged into another line
  if (i %in% used)
    return(NULL)

  ## identify consecutive observation (<5s)
  x <- timestamps[i]
  y <- timestamps[(i+1):length(timestamps)]

  # (subset same or consecutive days to reduce 
  # computation time of 'difftime')
  id_day <- which(as.Date(y) == as.Date(x) | 
                    as.Date(y) == (as.Date(x) + 1))
  y <- y[id_day]

  # (subset records within 5s from current observation)
  id_sec <- which(difftime(y, x, units = "secs") < 5)
  id <- id_day[id_sec]

  ## if consecutive observation(s) exist(s) and include address of 
  ## current observation, perform merge
  if (length(id) > 0 & 
        any(Hdata_soil[i+id, "address"] == Hdata_soil[i, "address"])) {

    for (j in 1:length(id)) {
      Hdata_soil_x <- data.frame(Hdata_soil[i, ])
      Hdata_soil_y <- data.frame(Hdata_soil[i+id[j], ])

      # overwrite all missing values in current line with values 
      # from consecutive line
      Hdata_soil_x[which(is.na(Hdata_soil_x) & !is.na(Hdata_soil_y))] <- 
        Hdata_soil_y[which(is.na(Hdata_soil_x) & !is.na(Hdata_soil_y))]

      # update information about merged lines
      used <- c(used, i, i+id[j])
    }

    # return merged line
    return(Hdata_soil_x)

  ## else return current line as is  
  } else {
    used <- c(used, i)
    return(data.frame(Hdata_soil[i, ]))
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,该代码需要很长时间才能执行,这似乎与difftime.

 >     user   system  elapsed 
 > 2209.504   99.389 2311.996 
Run Code Online (Sandbox Code Playgroud)