遍历列序列(相同作物相关数据)以在 R 中构建整洁的 rbind 数据集
Iterating across sequences of columns (of same crop-related data) to build tidy rbind dataset in R
我正在处理一个杂乱的宽格式作物数据集,其中每种作物都有六个相关变量(作物类型、作物种植面积、土壤中的氮、施用的氮、有机与常规和注释)。这 6 个变量有 50 组,总共 300 列,命名约定很不幸:c.0。 |一个.0。 | s.0。 | f.0。 | o.0。 | r.0。 |, .... , | c.23. | a.23 |第 23 节| f.23. |o.23。 | r.23。 |.
我想遍历列序列(与每个裁剪相关的 6 列),将每次迭代或单个裁剪保存为一个列表(或 df),其中包含常见的列名 c(CROP, CROP_ACREAGE、SOIL_N、APP_N、类型、注释)。迭代完所有作物后,我想通过绑定 50 个单独的作物数据集来构建一个整洁的 df。
下面是一个示例数据集,其中只有两组作物列、四个种植者、三年:
data <- tribble(
~grower, ~ YEAR, ~c.0., ~a.0., ~s.0., ~f.0., ~o.0., ~r.0., ~c.10., ~a.10, ~s.10., ~f.10., ~o.10., ~r.10.,
"Bob", 2014, "Kale, Baby", 7.0, 87.0, 126.0, "C", "", "Carrot", 16.0, 47.8, 137.0, "O", "",
"Janet", 2015, "Broccoli", 18.0, 68.2,162.0, "O", "", "Garlic", 25.0, 9.1, 152.3, "C", "",
"Chris", 2014, "Cabbage", 34.2, 8.6, 200.7, "C", "", "Cauliflower", 105.2, 113.0, 199.4, "O", "",
"Ted", 2016, "Kale", 12.2, 11.9, 120.2, "C", "", "Lettuce, Head", 55.2, 113.0, 166.5, "C", "NY"
)
我已经构建了可以运行的代码...但是那会非常低效:
build <- function(choice, iter){
a <- data %>% select(choice) %>%
rename(CROP = 3,
ACREAGE = 4,
N_SOIL = 5,
N_APPLIED = 6,
O_C = 7,
NOTES = 8)
saveRDS(a, file = paste0("./intermediate-data/",iter,".RDS"))
}
build(choice = c(1:8), iter = "crop1")
build(choice = c(1:2,9:14), iter = "crop2")
# use build() function until all 50 crops have been built into separate df's
然后我将从中间数据目录和 rbind() 中提取所有这些内容。
但我知道必须有一种更有效的方法...我可以在不直接指定它们的情况下遍历 6-crop-columns 的集合。有什么想法吗?
我们可以使用 pivot_longer
重塑为 'long' 格式
library(dplyr)
data %>%
pivot_longer(cols = contains("."), names_to = c(".value", "grp"),
names_pattern = "^([a-z])\.(\d+)\.") %>%
rename(CROP = c, ACREAGE = a, N_SOIL = s, N_APPLIED = f, O_C = o, NOTES = r)
-输出
# A tibble: 12 × 9
grower YEAR grp CROP ACREAGE N_SOIL N_APPLIED O_C NOTES
<chr> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <chr> <chr>
1 Bob 2014 0 Kale, Baby 7 87 126 C ""
2 Bob 2014 10 Carrot NA 47.8 137 O ""
3 Bob 2014 <NA> <NA> NA NA NA <NA> <NA>
4 Janet 2015 0 Broccoli 18 68.2 162 O ""
5 Janet 2015 10 Garlic NA 9.1 152. C ""
6 Janet 2015 <NA> <NA> NA NA NA <NA> <NA>
7 Chris 2014 0 Cabbage 34.2 8.6 201. C ""
8 Chris 2014 10 Cauliflower NA 113 199. O ""
9 Chris 2014 <NA> <NA> NA NA NA <NA> <NA>
10 Ted 2016 0 Kale 12.2 11.9 120. C ""
11 Ted 2016 10 Lettuce, Head NA 113 166. C "NY"
12 Ted 2016 <NA> <NA> NA NA NA <NA> <NA>
>
我正在处理一个杂乱的宽格式作物数据集,其中每种作物都有六个相关变量(作物类型、作物种植面积、土壤中的氮、施用的氮、有机与常规和注释)。这 6 个变量有 50 组,总共 300 列,命名约定很不幸:c.0。 |一个.0。 | s.0。 | f.0。 | o.0。 | r.0。 |, .... , | c.23. | a.23 |第 23 节| f.23. |o.23。 | r.23。 |.
我想遍历列序列(与每个裁剪相关的 6 列),将每次迭代或单个裁剪保存为一个列表(或 df),其中包含常见的列名 c(CROP, CROP_ACREAGE、SOIL_N、APP_N、类型、注释)。迭代完所有作物后,我想通过绑定 50 个单独的作物数据集来构建一个整洁的 df。
下面是一个示例数据集,其中只有两组作物列、四个种植者、三年:
data <- tribble(
~grower, ~ YEAR, ~c.0., ~a.0., ~s.0., ~f.0., ~o.0., ~r.0., ~c.10., ~a.10, ~s.10., ~f.10., ~o.10., ~r.10.,
"Bob", 2014, "Kale, Baby", 7.0, 87.0, 126.0, "C", "", "Carrot", 16.0, 47.8, 137.0, "O", "",
"Janet", 2015, "Broccoli", 18.0, 68.2,162.0, "O", "", "Garlic", 25.0, 9.1, 152.3, "C", "",
"Chris", 2014, "Cabbage", 34.2, 8.6, 200.7, "C", "", "Cauliflower", 105.2, 113.0, 199.4, "O", "",
"Ted", 2016, "Kale", 12.2, 11.9, 120.2, "C", "", "Lettuce, Head", 55.2, 113.0, 166.5, "C", "NY"
)
我已经构建了可以运行的代码...但是那会非常低效:
build <- function(choice, iter){
a <- data %>% select(choice) %>%
rename(CROP = 3,
ACREAGE = 4,
N_SOIL = 5,
N_APPLIED = 6,
O_C = 7,
NOTES = 8)
saveRDS(a, file = paste0("./intermediate-data/",iter,".RDS"))
}
build(choice = c(1:8), iter = "crop1")
build(choice = c(1:2,9:14), iter = "crop2")
# use build() function until all 50 crops have been built into separate df's
然后我将从中间数据目录和 rbind() 中提取所有这些内容。
但我知道必须有一种更有效的方法...我可以在不直接指定它们的情况下遍历 6-crop-columns 的集合。有什么想法吗?
我们可以使用 pivot_longer
library(dplyr)
data %>%
pivot_longer(cols = contains("."), names_to = c(".value", "grp"),
names_pattern = "^([a-z])\.(\d+)\.") %>%
rename(CROP = c, ACREAGE = a, N_SOIL = s, N_APPLIED = f, O_C = o, NOTES = r)
-输出
# A tibble: 12 × 9
grower YEAR grp CROP ACREAGE N_SOIL N_APPLIED O_C NOTES
<chr> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <chr> <chr>
1 Bob 2014 0 Kale, Baby 7 87 126 C ""
2 Bob 2014 10 Carrot NA 47.8 137 O ""
3 Bob 2014 <NA> <NA> NA NA NA <NA> <NA>
4 Janet 2015 0 Broccoli 18 68.2 162 O ""
5 Janet 2015 10 Garlic NA 9.1 152. C ""
6 Janet 2015 <NA> <NA> NA NA NA <NA> <NA>
7 Chris 2014 0 Cabbage 34.2 8.6 201. C ""
8 Chris 2014 10 Cauliflower NA 113 199. O ""
9 Chris 2014 <NA> <NA> NA NA NA <NA> <NA>
10 Ted 2016 0 Kale 12.2 11.9 120. C ""
11 Ted 2016 10 Lettuce, Head NA 113 166. C "NY"
12 Ted 2016 <NA> <NA> NA NA NA <NA> <NA>
>