类似的问题也有人问过,但还没有到这种程度。我有一个数据框架,其中包含如下信息
location field sample date height temp
loc1 fieldA 1_1 202001 1 86
loc1 fieldA 1_1 202001 10 92
loc1 fieldA 2_1 202001 1 88
loc1 fieldA 2_1 202001 10 82
loc1 filedA 1_2 202002 1 81
loc1 fieldA 1_2 202002 10 90
loc1 filedA 2_2 202002 1 88
loc1 filedA 2_2 202002 10 82
对于每个位置都有几个字段,对于每个字段有两个测量位置,对于每个位置都有两个测量高度。例如,在location1 fieldA中,样本1_1指的是第一个位置和第一个样本,并且在特定日期有两个高度。然后是location1, fieldA样本1_2,它指的是第一个位置,但第二个样本在第二个日期。这是lob和更多字段名的进一步扩展但这是基本的思想
理想情况下,我需要以下
location field 1_1_temp 1_10_temp 2_1_temp 2_10_temp date
loc1 fieldA 86 92 88 82 202001
loc1 fieldA 81 90 88 82 202002
对于每个位置和每个字段,我需要数据的时间序列。location1 fieldA将有一个时间序列,location1 fieldB将有一个时间序列,location2 fieldAA将有一个,以此类推。其中1_1_temp将是第一个位置,高度为1,1_10_temp将是第一个位置,高度为10,以此类推。我确信我需要整洁,但不确定如何做到这一点的程度。就像
df <- group_by(location) %>%
group_by(field) %>%
mutate()
任何帮助都是非常感激的。谢谢!假设filedA
是一个错误,会回答下一个代码你的问题吗?
library(dplyr)
library(tidyr)
df <- read.table(text = 'location field sample date height temp
loc1 fieldA 1_1 202001 1 86
loc1 fieldA 1_1 202001 10 92
loc1 fieldA 2_1 202001 1 88
loc1 fieldA 2_1 202001 10 82
loc1 fieldA 1_2 202002 1 81
loc1 fieldA 1_2 202002 10 90
loc1 fieldA 2_2 202002 1 88
loc1 fieldA 2_2 202002 10 82', header = TRUE)
df %>%
mutate(sample = sub("(\d)_\d","\1",sample)) %>%
pivot_wider(id_cols = c(location, field, date, sample), names_from = c(height), values_from = temp, names_prefix = "sample")
# A tibble: 4 × 6
location field date sample sample1 sample10
<chr> <chr> <int> <chr> <int> <int>
1 loc1 fieldA 202001 1 86 92
2 loc1 fieldA 202001 2 88 82
3 loc1 fieldA 202002 1 81 90
4 loc1 fieldA 202002 2 88 82
更新后的问题:
df %>%
mutate(sample = sub("(\d)_\d","\1",sample)) %>%
pivot_wider(id_cols = c(location, field, date), names_from = c(sample, height), values_from = temp, names_prefix = "sample") %>%
mutate(date = lubridate::ym(as.character(date)))
# A tibble: 2 × 7
location field date sample1_1 sample1_10 sample2_1 sample2_10
<chr> <chr> <date> <int> <int> <int> <int>
1 loc1 fieldA 2020-01-01 86 92 88 82
2 loc1 fieldA 2020-02-01 81 90 88 82