Reputation: 1584
Let's say this is my dataset
I would like to compute a new variable (mutate) considering always the same pattern (i.e.g, the lf_aparc_volume and the rh_aparc_volune; then the lh_bankssts and rh_bankssts). Therefore, the new variable needs to be the mean of one column with the column 2 spaces ahead, and so on. [In the real dataset, we have 30 columns between the two columns I want to take the mean].
In excel, after selecting the two variables, it will be a "drag and drop" to the right. Thus, when the result becomes "missing", the algorithm should stop.
I would like to remain in the tidyverse environment. Any suggestions?
Edit with the answer (thanks to Ian Campbell) If someone is facing the same situation, please see the following code:
ds %>% #get the dataset
pivot_longer(-identificacao, names_to = "variable", values_to = "values") %>% #re-arrange the way we see the ds
separate(variable, into = c("group","variable"),
sep = "_", extra = "merge") %>% #fix names
pivot_wider(id_cols = c("identificacao","group"),
names_from = "variable", values_from = "values") %>% #wide format
group_by(identificacao) %>% #now I'll group the take the means
mutate(mean_aparc = mean(aparc_volume)) %>%
mutate(mean_bankssts = mean(bankssts_volume)) %>%
distinct(identificacao, .keep_all = TRUE) #keep only one identification per row
Code:
ds <-structure(list(identificacao = c("3004U", "77584X", "25917G",
"39895C", "20597Y", "64085M", "51573F", "42221E", "58658E", "8983C",
"18516K", "27050E"), lh_aparc_volume = c(2112, 2081, 2050, 2350,
2250, 1730, 1874, 1821, 2004, 1928, 1844, 2900), lh_bankssts_volume = c(1750,
1654, 1344, 1876, 1366, 1424, 1416, 1521, 1231, 2415, 938, 1356
), rh_aparc_volume = c(1797, 1895, 1386, 1875, 2123, 1457, 1754,
2478, 1670, 1613, 1702, 1873), rh_bankssts_volume = c(1951, 1991,
1774, 2539, 1830, 2564, 2433, 1092, 1803, 2009, 1609, 1787)), row.names = c(NA,
-12L), class = c("tbl_df", "tbl", "data.frame"))
ds
Upvotes: 0
Views: 57
Reputation: 24878
Here's an approach with bind_cols
and map2
:
library(dplyr)
library(purrr)
cols.ahead <- 2
ds %>%
bind_cols(., map2(seq(2,ceiling(ncol(.)/2)),seq(2,ceiling(ncol(.)/2)) + cols.ahead,
~ setNames((ds[,.x]+ds[,.y])/2,
paste0(gsub(".+_(\\w+)_.+","\\1",names(ds)[.x]),"_mean"))))
# A tibble: 12 x 7
identificacao lh_aparc_volume lh_bankssts_volume rh_aparc_volume rh_bankssts_volume aparc_mean bankssts_mean
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 3004U 2112 1750 1797 1951 1954. 1850.
2 77584X 2081 1654 1895 1991 1988 1822.
3 25917G 2050 1344 1386 1774 1718 1559
4 39895C 2350 1876 1875 2539 2112. 2208.
5 20597Y 2250 1366 2123 1830 2186. 1598
6 64085M 1730 1424 1457 2564 1594. 1994
7 51573F 1874 1416 1754 2433 1814 1924.
8 42221E 1821 1521 2478 1092 2150. 1306.
9 58658E 2004 1231 1670 1803 1837 1517
10 8983C 1928 2415 1613 2009 1770. 2212
11 18516K 1844 938 1702 1609 1773 1274.
12 27050E 2900 1356 1873 1787 2386. 1572.
Another "tidyverse" approach would be tidyr:pivot_longer
:
library(dplyr)
library(tidyr)
ds %>%
pivot_longer(-identificacao, names_to = "variable", values_to = "values") %>%
separate(variable, into = c("group","variable"),
sep = "_", extra = "drop") %>%
pivot_wider(id_cols = c("identificacao","variable"),
names_from = "group", values_from = "values") %>%
mutate(mean = (lh + rh)/2) %>%
pivot_wider(id_cols = "identificacao",
names_from = "variable",
values_from = c("lh","rh","mean"))
# A tibble: 12 x 7
identificacao lh_aparc lh_bankssts rh_aparc rh_bankssts mean_aparc mean_bankssts
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 3004U 2112 1750 1797 1951 1954. 1850.
2 77584X 2081 1654 1895 1991 1988 1822.
3 25917G 2050 1344 1386 1774 1718 1559
4 39895C 2350 1876 1875 2539 2112. 2208.
5 20597Y 2250 1366 2123 1830 2186. 1598
6 64085M 1730 1424 1457 2564 1594. 1994
7 51573F 1874 1416 1754 2433 1814 1924.
8 42221E 1821 1521 2478 1092 2150. 1306.
9 58658E 2004 1231 1670 1803 1837 1517
10 8983C 1928 2415 1613 2009 1770. 2212
11 18516K 1844 938 1702 1609 1773 1274.
12 27050E 2900 1356 1873 1787 2386. 1572.
Obviously this moves whatever lh
and rh
are to the end of the column name. If this is a dealbreaker, you could use rename_at
.
Upvotes: 1
Reputation: 33
What is the problem with the simple mutate?
View(ds %>% mutate(col1 = (lh_aparc_volume + rh_aparc_volume) /2 ,col2 = (lh_bankssts_volume + rh_bankssts_volume)/2))
Upvotes: 0