在R中读取多个头文件

时间:2019-06-21 15:40:46

标签: r

我正在读取一个Excel文件,其中的数据包含两个标题:

  • 变量名
  • 测量深度(2 m或25 m)

enter image description here

这是数据的子集。

df <- structure(
  list(
    date_deployed = c(NA, "02/05/2015", "04/05/2015"),
    chl_a_ug_m_2_d_1 = c("2 m", "3.3908588202404242", "10.887607383329465"),
    x4 = c("25 m", "15.023264970645787", "7.534785609849461")
  ),
  row.names = c(
    NA,
    -3L
  ),
  class = c("tbl_df", "tbl", "data.frame")
)

df
#>   date_deployed   chl_a_ug_m_2_d_1                 x4
#> 1          <NA>                2 m               25 m
#> 2    02/05/2015 3.3908588202404242 15.023264970645787
#> 3    04/05/2015 10.887607383329465  7.534785609849461

是否有一种优雅的方式来读取此类文件,因此数据看起来像这样:

data.frame(
  date_deployed = c("02/05/2015", "02/05/2015", "04/05/2015", "04/05/2015"),
  chl_a_ug_m_2_d_1 = c(3.3908588202404242, 15.023264970645787, 10.887607383329465, 7.534785609849461),
  depth = c(2, 25, 2, 25)
)
#>   date_deployed chl_a_ug_m_2_d_1 depth
#> 1    02/05/2015         3.390859     2
#> 2    02/05/2015        15.023265    25
#> 3    04/05/2015        10.887607     2
#> 4    04/05/2015         7.534786    25

我本来打算将tidyxlunpivotr一起使用,但是我无法理解。

2 个答案:

答案 0 :(得分:0)

我对优雅并不了解,但是我可以找到一些带有重塑和正则表达式的解决方案。可以标准化到更多列...

最好的解决方案是改善csv格式:)

library(data.table)
library(stringi)

# convert to data.table
dt <- as.data.table(df)

# clean it so that the artifical first row is removed, name moved in to column name
setnames(dt, names(dt)[2:3],
         paste(names(dt)[2], dt[1, c(2:3)], sep=">>"))
dt <- dt[-1,]

# wide to long format & view
dt2 <- melt(dt, id.vars = "date_deployed")
dt2[]

# need to extract depth integer, and rename the columns, using original one in df
setnames(dt2, c("variable", "value"), c("depth", names(df)[2]))
dt2[, depth :=  stri_extract_all_regex(tstrsplit(depth, ">>")[[2]], "[0-9]+") ]
dt2[]

# back to data.frame format
out <- as.data.frame(dt2)

答案 1 :(得分:0)

也许可以通过以下方法解决问题。

header1 <- names(df)
header2 <- unlist(df[1, 2:3])
names(df)[2:3] <- header2
df <- df[-1, ]
long_df <- reshape2::melt(df, id.vars = "date_deployed")
names(long_df)[2] <- header1[2]
long_df[[3]] <- as.numeric(as.character(long_df[[3]]))

long_df
#  date_deployed chl_a_ug_m_2_d_1              value
#1    02/05/2015              2 m 3.3908588202404242
#2    04/05/2015              2 m 10.887607383329465
#3    02/05/2015             25 m 15.023264970645787
#4    04/05/2015             25 m  7.534785609849461