Here's a tidyverse solution.
Example data.
df <- structure(list(Family = c("AKCO", "AKDC", "ALZC", "ARCT", "COCZ"),
Env1_Females = c(2L, 3L, 0L, 1L, 1L), Env1_Males = c(4L,
3L, 0L, 5L, 2L), Env2_Females = c(8L, 3L, 5L, 4L, 1L), Env2_Males = c(2L,
7L, 4L, 6L, 2L), P1 = c("AK4", "AK6", "AL2", "AR3", "CO5"
), P2 = c("CO1", "DC2", "CZ4", "CT4", "CZ2")), class = "data.frame", row.names = c(NA,
-5L))
Here's the code to generate the output.
library("tidyverse")
df <- df %>%
pivot_longer(starts_with("Env"), names_sep="_", values_to="count", names_to=c("Env", "Sex")) %>%
mutate(Sex=str_sub(Sex, end=1), Env=str_extract(Env, "\\d+$")) %>%
uncount(count) %>%
group_by(Family) %>%
mutate(ID=str_c(Family, "-", seq_len(n()))) %>%
ungroup %>%
select(-Family)
And the desired output.
>df
# A tibble: 63 x 5
P1 P2 Env Sex ID
<chr> <chr> <chr> <chr> <chr>
1 AK4 CO1 1 F AKCO-1
2 AK4 CO1 1 F AKCO-2
3 AK4 CO1 1 M AKCO-3
4 AK4 CO1 1 M AKCO-4
5 AK4 CO1 1 M AKCO-5
6 AK4 CO1 1 M AKCO-6
7 AK4 CO1 2 F AKCO-7
8 AK4 CO1 2 F AKCO-8
9 AK4 CO1 2 F AKCO-9
10 AK4 CO1 2 F AKCO-10
# ... with 53 more rows
It might make it easier to answer the question if you had a few example lines from the data.frame you are starting with, and an example of what you want the output to look like.
Good suggestion! The top is what I have and the bottom is an example of what I'm looking for
Example for just the first row from first data frame into second dataframe.