Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R - Find first non zero elements per groups in data.table

Tags:

r

data.table

I have a data table in R that looks like this:

    State  City Maturing  Soil 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
 1:    PR CityA    Early SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 40 40 40 40
 2:    PR CityA    Early  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 20 20 20 20 20 20
 3:    PR CityA    Early  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 40 30 30 20 20 20 20 20 20
 4:    PR CityA   Medium SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 40 40 40 40 40
 5:    PR CityA   Medium  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 20 20 20 20 20 20 30
 6:    PR CityA   Medium  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 20 20 20 20 20 20 20
 7:    PR CityA     Late SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 30 30 30 40 40  0
 8:    PR CityA     Late  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 20 20 20 20 20 30 30
 9:    PR CityA     Late  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 30 20 20 20 20 20 20 20 20 20
10:    PR CityB    Early SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 30 30 30 30 30
11:    PR CityB    Early  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 20 20 20 20 20 20 20
12:    PR CityB    Early  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 30 20 20 20 20 20 20 20 20 20
13:    PR CityB   Medium SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 30 20 20 30 30 30
14:    PR CityB   Medium  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 30 30 20 20 20 20 20 20 20 20
15:    PR CityB   Medium  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 20 20 20 20 20 20 20 20 20 20
16:    PR CityB     Late SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 20 20 20 20 20 30 40
17:    PR CityB     Late  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 20 20 20 20 20 20 20 20 20 20
18:    PR CityB     Late  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 20 20 20 20 20 20 20 20 20 20 20
19:    RS CityC    Early SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 40 40  0
20:    RS CityC    Early  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 30 30 30 40
21:    RS CityC    Early  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 30 30 20 30 20 30 30
22:    RS CityC   Medium SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 40 40 40  0  0
23:    RS CityC   Medium  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 30 30 30 30 30 30  0
24:    RS CityC   Medium  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 30 30 20 20 20 30 40
25:    RS CityC     Late SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 40 30 30 30 40  0  0
26:    RS CityC     Late  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 30 30 20 30 30 40  0
27:    RS CityC     Late  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 20 20 20 20 20 20 30 40
28:    RS CityD    Early SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 30 30 30 30 30 30 30 40
29:    RS CityD    Early  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 20 20 20 20 20 20 20 20 30
30:    RS CityD    Early  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 20 20 20 20 20 20 20 20 20 20
31:    RS CityD   Medium SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 30 30 30 20 20 30 30  0
32:    RS CityD   Medium  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 20 20 20 20 20 20 20 20 40
33:    RS CityD   Medium  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 20 20 20 20 20 20 20 20 20 20
34:    RS CityD     Late SANDY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40 30 20 20 20 20 20 30 40  0
35:    RS CityD     Late  SILT 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 30 20 20 20 20 20 20 20 30  0
36:    RS CityD     Late  CLAY 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 20 20 20 20 20 20 20 20 20 30
    State  City Maturing  Soil 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

Columns named 1 to 36 represent ten-day periods in the year where planting is recommended. I want to extract the earliest recommended planting date for each State, Maturing and Soil. In other words, I want to extract the column name for the first ten-day period which is not 0 for the aforementioned groups.

For the above example, the expected outcome would be:

State  Maturing  Soil   Earliest
PR     Early     SANDY  30
PR     Early     SILT   26
PR     Early     CLAY   26
PR     Medium    SANDY  27
PR     Medium    SILT   26
PR     Medium    CLAY   26
PR     Late      SANDY  26
PR     Late      SILT   26
PR     Late      CLAY   26
RS     Early     SANDY  28
RS     Early     SILT   27
RS     Early     CLAY   27
RS     Medium    SANDY  27
RS     Medium    SILT   27
RS     Medium    CLAY   27
RS     Late      SANDY  27
RS     Late      SILT   27
RS     Late      CLAY   27

How can I achieve this?

Data can be reproduced with the following code:

library(data.table)

dat <- data.table(structure(list(State = rep(c("PR","RS"), each=18),
City = rep(c("CityA","CityB","CityC","CityD"), each=9),
Maturing = rep(rep(c("Early","Medium","Late"), each=3), 4),
Soil = rep(c("SANDY","SILT","CLAY"), 12), `1` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `2` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `3` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `4` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `5` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `6` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `7` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `8` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `9` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `10` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `11` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `12` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `13` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `14` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `15` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `16` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `17` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `18` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `19` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `20` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `21` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `22` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `23` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `24` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `25` = c(0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `26` = c(0L, 0L, 40L, 0L, 0L, 
40L, 0L, 40L, 30L, 0L, 40L, 30L, 0L, 30L, 30L, 40L, 30L, 20L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), `27` = c(0L, 0L, 
40L, 0L, 0L, 40L, 0L, 40L, 30L, 0L, 40L, 30L, 40L, 30L, 20L, 
40L, 20L, 20L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 30L, 20L, 
40L, 30L, 20L, 40L, 30L, 20L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L), `28` = c(0L, 0L, 40L, 0L, 40L, 30L, 0L, 30L, 20L, 0L, 30L, 
20L, 40L, 30L, 20L, 30L, 20L, 20L, 0L, 0L, 40L, 0L, 0L, 40L, 
0L, 40L, 40L, 30L, 20L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 20L, 
20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), `29` = c(0L, 0L, 30L, 
0L, 30L, 30L, 40L, 30L, 20L, 0L, 30L, 20L, 30L, 20L, 20L, 30L, 
20L, 20L, 0L, 40L, 30L, 0L, 30L, 30L, 40L, 30L, 20L, 30L, 20L, 
20L, 30L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 
20L, 20L, 20L), `30` = c(0L, 30L, 30L, 40L, 20L, 20L, 30L, 20L, 
20L, 40L, 20L, 20L, 30L, 20L, 20L, 20L, 20L, 20L, 0L, 40L, 30L, 
40L, 30L, 30L, 40L, 30L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 20L, 
20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), `31` = c(40L, 
20L, 20L, 40L, 20L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 30L, 20L, 
20L, 20L, 20L, 20L, 0L, 30L, 30L, 40L, 30L, 30L, 30L, 30L, 20L, 
30L, 20L, 20L, 30L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 
20L, 20L, 20L, 20L, 20L), `32` = c(40L, 20L, 20L, 40L, 20L, 20L, 
30L, 20L, 20L, 30L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 40L, 
30L, 20L, 40L, 30L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 20L, 20L, 
20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L
), `33` = c(40L, 20L, 20L, 40L, 20L, 20L, 30L, 20L, 20L, 30L, 
20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 40L, 30L, 30L, 40L, 30L, 
20L, 30L, 30L, 20L, 30L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 
20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), `34` = c(40L, 20L, 
20L, 40L, 20L, 20L, 40L, 20L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 
20L, 20L, 20L, 40L, 30L, 20L, 40L, 30L, 20L, 40L, 30L, 20L, 30L, 
20L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 
20L, 30L, 20L, 20L), `35` = c(40L, 20L, 20L, 40L, 20L, 20L, 40L, 
30L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 30L, 20L, 20L, 40L, 30L, 
30L, 0L, 30L, 30L, 0L, 40L, 30L, 30L, 20L, 20L, 30L, 20L, 20L, 
40L, 30L, 20L, 20L, 20L, 20L, 30L, 20L, 20L, 30L, 20L, 20L), 
    `36` = c(40L, 20L, 20L, 40L, 30L, 20L, 0L, 30L, 20L, 30L, 
    20L, 20L, 30L, 20L, 20L, 40L, 20L, 20L, 0L, 40L, 30L, 0L, 
    0L, 40L, 0L, 0L, 40L, 40L, 30L, 20L, 0L, 40L, 20L, 0L, 0L, 
    30L, 30L, 20L, 20L, 40L, 30L, 20L, 0L, 30L, 20L)), row.names = c(NA, 
-45L), class = "data.frame"))
like image 435
thiagoveloso Avatar asked Jul 08 '26 03:07

thiagoveloso


2 Answers

Updated

I have modified my code to have your desired result, however this is not your preferred data.table solution. The point we didn't get is that the combinations of grouping variables are not always unique so this was not basically a row-wise operation and needed grouping while considering the earliest date in each group. The only problem with my output is the orders of levels for Maturing and Soil variables which differ from the order obs in your output. It can be fixed.

library(dplyr)
library(tidyr)
library(purrr)

dat %>%
  mutate(Earliest = pmap(dat %>% 
                           select(`1`:`36`), ~ names(c(...))[c(...) != 0][1])) %>%
  select(-c(`1`:`36`)) %>%
  unnest(cols = c(Earliest)) %>% 
  group_by(State, Maturing, Soil) %>% 
  mutate(Earliest = as.numeric(Earliest)) %>%
  summarise(across(Earliest, ~ min(.x))) %>%
  ungroup()


# A tibble: 18 x 4
   State Maturing Soil  Earliest
   <chr> <chr>    <chr>    <dbl>
 1 PR    Early    CLAY        26
 2 PR    Early    SANDY       30
 3 PR    Early    SILT        26
 4 PR    Late     CLAY        26
 5 PR    Late     SANDY       26
 6 PR    Late     SILT        26
 7 PR    Medium   CLAY        26
 8 PR    Medium   SANDY       27
 9 PR    Medium   SILT        26
10 RS    Early    CLAY        27
11 RS    Early    SANDY       28
12 RS    Early    SILT        27
13 RS    Late     CLAY        27
14 RS    Late     SANDY       27
15 RS    Late     SILT        27
16 RS    Medium   CLAY        27
17 RS    Medium   SANDY       27
18 RS    Medium   SILT        27
like image 78
Anoushiravan R Avatar answered Jul 09 '26 17:07

Anoushiravan R


Inspired by the solution of Anoushiravan (very well done) I tried a solution with dyplr and tidyr alone and keep the desired order of the OP.

Here is my solution (with comments):

library(dplyr)
library(tidyr)

# relevel Soil for same Output as desired
order_Soil <- c("SANDY", "SILT", "CLAY")

dat1 <- dat %>%
  select(where(~ any(. != 0)), -City) %>%           #remove all 0 columns
  pivot_longer(                                     #bring in longformat
    cols = c(`26`:`36`), 
    names_to = "Names",
    values_to = "Values"
  ) %>% 
  mutate(Soil = factor(Soil,                        #to keep the desired order
                       levels = order_Soil)) %>% 
  filter(Values != 0) %>%                           #remove rows with any 0
  group_by(State, Maturing, Soil) %>%
  summarise(Earliest = min(Names))                  #Summarize the Earliest

Output:

   State Maturing Soil  Earliest
   <chr> <chr>    <fct> <chr>   
 1 PR    Early    SANDY 30      
 2 PR    Early    SILT  26      
 3 PR    Early    CLAY  26      
 4 PR    Late     SANDY 26      
 5 PR    Late     SILT  26      
 6 PR    Late     CLAY  26      
 7 PR    Medium   SANDY 27      
 8 PR    Medium   SILT  26      
 9 PR    Medium   CLAY  26      
10 RS    Early    SANDY 28      
11 RS    Early    SILT  27      
12 RS    Early    CLAY  27      
13 RS    Late     SANDY 27      
14 RS    Late     SILT  27      
15 RS    Late     CLAY  27      
16 RS    Medium   SANDY 27      
17 RS    Medium   SILT  27      
18 RS    Medium   CLAY  27 
like image 24
TarJae Avatar answered Jul 09 '26 18:07

TarJae



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!