library(dplyr)
library(haven)
library(knitr)

Objective

Verifying ASI unit-level extraction against MoSPI’s published aggregates (factories, workers, value of products), and deriving total output and output per worker.

Data & Method

Validation Table

Indicator MoSPI Published R Pipeline Result Status
Total Number of Factories 2,60,061 2,60,061 Verified
Number of Workers 1,55,19,957 1,55,19,957 Verified
Value of Products & By-Products 1,36,07,99,546 1,36,07,99,546 Verified
Value of Output 1,53,27,16,609 1,53,27,16,609 Verified
Output per Worker Not Published 98,758 Derived

Data Extraction & Pipeline Execution

# Standardize DSL key across blocks
blka <- blka %>%
  rename(dsl = a1) %>%
  zap_labels() %>%
  mutate(dsl = trimws(as.character(dsl)))

blkc <- blkc %>%
  rename(dsl = ac01) %>%
  zap_labels() %>%
  mutate(dsl = trimws(as.character(dsl)))

blke_emp <- blke_emp %>%
  rename(dsl = AE01) %>%
  zap_labels() %>%
  mutate(dsl = trimws(as.character(dsl)))

blkf <- blkf %>%
  rename(dsl = AF01) %>%
  zap_labels() %>%
  mutate(dsl = trimws(as.character(dsl)))

blkg <- blkg %>%
  rename(dsl = AG01) %>%
  zap_labels() %>%
  mutate(dsl = trimws(as.character(dsl)))

blkj <- blkj %>%
  rename(dsl = AJ01) %>%
  zap_labels() %>%
  mutate(dsl = trimws(as.character(dsl)))
# Total factories (A12 in 1, 2, 3, 4)
total_factories <- blka %>%
  filter(a12 %in% c(1, 2, 3, 4)) %>%
  summarise(count = sum(mult * a11, na.rm = TRUE))

total_factories
## # A tibble: 1 × 1
##     count
##     <dbl>
## 1 260061.
# Breakdown: Operating vs non-operating
operating_factories <- blka %>%
  filter(a12 %in% c(1, 2, 3)) %>%
  summarise(operating = sum(mult * a11, na.rm = TRUE))

closed_factories <- blka %>%
  filter(a12 == 4) %>%
  summarise(non_operating = sum(mult * a11, na.rm = TRUE))

operating_factories
## # A tibble: 1 × 1
##   operating
##       <dbl>
## 1   212990.
closed_factories
## # A tibble: 1 × 1
##   non_operating
##           <dbl>
## 1        47071.
# Fixed Capital from Block C 
fixed_cap_df <- blkc %>%
  filter(c_11 == 10) %>%
  select(dsl, c_113)

merged_ac <- blka %>%
  left_join(fixed_cap_df, by = "dsl")

fixed_capital_est <- merged_ac %>%
  filter(a12 %in% c(1, 2, 3, 4)) %>%
  summarise(
    raw_sum = sum(coalesce(c_113, 0) * mult, na.rm = TRUE),
    in_lakhs = round(sum(coalesce(c_113, 0) * mult, na.rm = TRUE) / 100000)
  )

fixed_capital_est
## # A tibble: 1 × 2
##   raw_sum  in_lakhs
##     <dbl>     <dbl>
## 1 4.62e13 462409035
# Worker count from Block E (mandays/workers categories 4 & 5)
worker_aggregates <- blke_emp %>%
  filter(EI1 %in% c(4, 5)) %>%
  group_by(dsl) %>%
  summarise(EI6 = sum(EI6, na.rm = TRUE))

merged_ace <- merged_ac %>%
  left_join(worker_aggregates, by = "dsl")

total_workers <- merged_ace %>%
  filter(a12 %in% c(1, 2, 3, 4)) %>%
  summarise(est_workers = round(sum(coalesce(EI6, 0) * mult, na.rm = TRUE)))

total_workers
## # A tibble: 1 × 1
##   est_workers
##         <dbl>
## 1    15519957
# Products and By-products from Block J (codes 12 & 13) + Block G (G4 & G7)
j_products <- blkj %>%
  filter(J11 %in% c(12, 13)) %>%
  group_by(dsl) %>%
  summarise(J113 = sum(J113, na.rm = TRUE))

g_products <- blkg %>%
  select(dsl, G4, G7)

merged_products <- merged_ace %>%
  left_join(j_products, by = "dsl") %>%
  left_join(g_products, by = "dsl")

value_of_products <- merged_products %>%
  filter(a12 %in% c(1, 2, 3, 4)) %>%
  mutate(
    J113 = ifelse(is.na(J113), 0, J113),
    G4   = ifelse(is.na(G4), 0, G4),
    G7   = ifelse(is.na(G7), 0, G7)) %>%
  summarise(
    total_val = round(sum((coalesce(J113, 0) + G4 + G7) * mult / 100, na.rm = TRUE)))

value_of_products
## # A tibble: 1 × 1
##       total_val
##           <dbl>
## 1 1360799546072
value_of_products_per1000<-value_of_products/1000
value_of_products_per1000
##    total_val
## 1 1360799546
# Receipts/Other output from Block G (G1, G2, G3, G6, G8, G11) and Block F (F7)
g_other <- blkg %>%
  select(dsl, G1, G2, G3, G6, G8, G11)

f_other <- blkf %>%
  select(dsl, F7)

merged_other <- merged_ace %>%
  left_join(g_other, by = "dsl") %>%
  left_join(f_other, by = "dsl")

other_output <- merged_other %>%
  filter(a12 %in% c(1, 2, 3, 4)) %>%
  mutate(
    G1  = ifelse(is.na(G1), 0, G1),
    G2  = ifelse(is.na(G2), 0, G2),
    G3  = ifelse(is.na(G3), 0, G3),
    G6  = ifelse(is.na(G6), 0, G6),
    G8  = ifelse(is.na(G8), 0, G8),
    G11 = ifelse(is.na(G11), 0, G11),
    F7  = ifelse(is.na(F7), 0, F7)) %>%
  summarise(
    other_val = round(sum((G1 + G2 + G3 + G6 + G8 + G11 + F7) * mult / 100, na.rm = TRUE))
  )

other_output
## # A tibble: 1 × 1
##      other_val
##          <dbl>
## 1 171917062687
value_of_otheroutput_per1000<-other_output/1000
value_of_otheroutput_per1000
##   other_val
## 1 171917063
# Combine value of products and other output to get total output
VALUE_OF_OUTPUT<-value_of_products_per1000+value_of_otheroutput_per1000
VALUE_OF_OUTPUT
##    total_val
## 1 1532716609

Direct calculation matching MoSPI target (98,758)

output_per_worker_val <- round((VALUE_OF_OUTPUT / total_workers) * 1000) 
#In ASI data, output is recorded in thousands of Rupees

output_per_worker_val
##   total_val
## 1     98758