Извлечение имен столбцов для каждого столбца в кадре данных, где значение не является NA для определенного диапазона столбцов в функции dplyr - PullRequest
3 голосов
/ 20 марта 2020

Я пытаюсь написать функцию, которая принимает фрейм данных, столбец, который определяет, выполняется ли указанное условие c для подмножества фрейма, столбец со значением числового значения c, предложение группировки и подмножество назвать в качестве аргументов.

Я хотел бы, чтобы функция затем проверила, какой из столбцов в определенном диапазоне имеет значение, отличное от NA, а затем извлекла имена столбцов этих столбцов и добавила их в таблицу dplyr, созданную функция для каждой итоговой строки, которую dplyr генерирует согласно предложению группировки. Я делаю это на сотнях подмножеств гораздо большего и более сложного информационного кадра, поэтому мне нужна функция, которую я могу использовать снова и снова.

Пример набора данных следующий: я обновил его с расширенным набором данных извинения для тех, кто пытался помочь с другим:

structure(list(superKey = c("12015", "12016", "12017", "12018", 
"22015", "22016", "22017", "22018", "32015", "1722016", "1722017", 
"1722018", "1732015", "1732016", "1732017", "1732018", "1742015", 
"1752015", "1752016", "1752017", "1762015", "1762018", "1772016", 
"1772017", "1772018", "1782015", "1782016", "1782017", "1782018", 
"1792015", "1792016", "1792017", "1792018", "1802015", "1812018", 
"1822016", "1832015", "1832017", "1842015", "1842016", "1842017", 
"1842018", "1852016", "1852017", "1852018", "2112018", "2122015", 
"2122016", "2122017", "2122018", "2132015", "2132016", "2132017", 
"2132018", "2142015", "2142016", "2142017", "2142018", "2152015", 
"2152016", "2152017", "2152018", "2162016", "2162017", "2172015", 
"2172016", "2172017", "2172018", "2182015", "2182016", "2182017", 
"2182018", "2192016", "2192017", "2192018", "2202015", "2202016", 
"2202017", "2202018", "2212015", "2212016", "2212017", "2212018", 
"2222015", "2222018", "2232015", "2232016", "2232017", "2232018", 
"2242015", "2242016", "2302018", "2312015", "2312016", "2312017", 
"2312018", "2322016", "2322017", "2332015", "2332016", "2332017", 
"2332018", "2342016", "2342017", "2432018", "2442015", "2442016"
), reportDate = c("2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", 
"2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", "2015-12-31", 
"2016-12-31", "2017-12-31", "2018-12-31", "2015-12-31", "2016-12-31", 
"2017-12-31", "2018-12-31", "2015-12-31", "2015-12-31", "2016-12-31", 
"2017-12-31", "2015-12-31", "2018-12-31", "2016-12-31", "2017-12-31", 
"2018-12-31", "2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", 
"2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", "2015-12-31", 
"2018-12-31", "2016-12-31", "2015-12-31", "2017-12-31", "2015-12-31", 
"2016-12-31", "2017-12-31", "2018-12-31", "2016-12-31", "2017-12-31", 
"2018-12-31", "2018-12-31", "2015-12-31", "2016-12-31", "2017-12-31", 
"2018-12-31", "2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", 
"2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", "2015-12-31", 
"2016-12-31", "2017-12-31", "2018-12-31", "2016-12-31", "2017-12-31", 
"2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", "2015-12-31", 
"2016-12-31", "2017-12-31", "2018-12-31", "2016-12-31", "2017-12-31", 
"2018-12-31", "2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", 
"2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", "2015-12-31", 
"2018-12-31", "2015-12-31", "2016-12-31", "2017-12-31", "2018-12-31", 
"2015-12-31", "2016-12-31", "2018-12-31", "2015-12-31", "2016-12-31", 
"2017-12-31", "2018-12-31", "2016-12-31", "2017-12-31", "2015-12-31", 
"2016-12-31", "2017-12-31", "2018-12-31", "2016-12-31", "2017-12-31", 
"2018-12-31", "2015-12-31", "2016-12-31"), employerClass = c("class1", 
"class1", "class1", "class1", "class1", "class1", "class1", "class1", 
"class1", "class1", "class1", "class1", "class1", "class1", "class1", 
"class1", "class1", "class1", "class1", "class1", "class1", "class1", 
"class1", "class1", "class1", "class1", "class1", "class1", "class1", 
"class1", "class1", "class1", "class1", "class1", "class1", "class1", 
"class1", "class1", "class1", "class1", "class1", "class1", "class1", 
"class1", "class1", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class1", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2", "class2", "class2", "class2", "class2", "class2", "class2", 
"class2"), healthRegion = c("Region1", "Region1", "Region1", 
"Region1", "Region2", "Region2", "Region2", "Region2", "Region2", 
"Region3", "Region3", "Region3", "Region4", "Region4", "Region4", 
"Region4", "Region3", "Region3", "Region3", "Region3", "Region3", 
"Region3", "Region2", "Region2", "Region2", "Region3", "Region3", 
"Region3", "Region3", "Region2", "Region2", "Region2", "Region2", 
"Region3", "Region4", "Region4", "Region3", "Region3", "Region1", 
"Region1", "Region1", "Region1", "Region2", "Region2", "Region2", 
"Region2", "Region2", "Region2", "Region2", "Region2", "Region3", 
"Region3", "Region3", "Region3", "Region3", "Region3", "Region3", 
"Region3", "Region4", "Region4", "Region4", "Region4", "Region2", 
"Region2", "Region3", "Region3", "Region3", "Region3", "Region3", 
"Region3", "Region3", "Region3", "Region1", "Region1", "Region1", 
"Region3", "Region3", "Region3", "Region3", "Region4", "Region4", 
"Region4", "Region4", "Region3", "Region3", "Region3", "Region3", 
"Region3", "Region3", "Region4", "Region4", "Region1", "Region1", 
"Region1", "Region1", "Region1", "Region3", "Region3", "Region2", 
"Region2", "Region2", "Region2", "Region1", "Region1", "Region1", 
"Region2", "Region2"), contactID = c(1, 1, 1, 1, 2, 2, 2, 2, 
3, 172, 172, 172, 173, 173, 173, 173, 174, 175, 175, 175, 176, 
176, 177, 177, 177, 178, 178, 178, 178, 179, 179, 179, 179, 180, 
181, 182, 183, 183, 184, 184, 184, 184, 185, 185, 185, 211, 212, 
212, 212, 212, 213, 213, 213, 213, 214, 214, 214, 214, 215, 215, 
215, 215, 216, 216, 217, 217, 217, 217, 218, 218, 218, 218, 219, 
219, 219, 220, 220, 220, 220, 221, 221, 221, 221, 222, 222, 223, 
223, 223, 223, 224, 224, 230, 231, 231, 231, 231, 232, 232, 233, 
233, 233, 233, 234, 234, 243, 244, 244), funder1 = c(500, 500, 
500, 500, 500, 500, 500, 500, NA, NA, NA, NA, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, NA, NA, NA, 
NA, 500, 500, 500, 500, 500, 500, 500, 500, 500, NA, NA, NA, 
NA, NA, NA, NA, 500, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 500, 500, 500, 500, NA, NA, 500, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 500, NA, NA, NA, NA, 
NA, NA, NA, 500, 500, 500, 500, NA, NA, 500, NA, NA), funder2 = c(1000, 
1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, NA, NA, NA, NA, 
NA, NA, NA, 1000, NA, NA, NA, 1000, NA, 1000, 1000, 1000, NA, 
NA, 1000, 1000, 1000, 1000, 1000, 1000, 1000, NA, NA, 1000, 1000, 
1000, 1000, 1000, 1000, NA, NA, NA, 1000, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 1000, 1000, 1000, 1000, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, 1000, 1000, 1000, 1000, NA, NA, NA, NA, NA, NA, 
NA, 1000, 1000, NA, NA, NA, NA, 1000, 1000, NA, NA, NA), funder3 = c(NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), funder4 = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA), funder5 = c(2500, 2500, 
2500, 2500, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, 2500, 2500, 2500, 2500, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 2500, 2500, NA, NA, NA), others = c(3000, 
3000, 3000, 3000, NA, NA, NA, NA, 3000, 3000, 3000, 3000, NA, 
NA, NA, NA, 3000, NA, NA, NA, 3000, NA, NA, NA, NA, 3000, 3000, 
3000, 3000, 3000, 3000, 3000, 3000, NA, NA, NA, NA, NA, 3000, 
3000, 3000, 3000, NA, NA, NA, NA, NA, NA, NA, NA, 3000, 3000, 
3000, NA, NA, NA, NA, NA, NA, NA, 3000, 3000, 3000, 3000, 3000, 
3000, 3000, 3000, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, 3000, 3000, NA, NA, 3000, 3000, 3000, 
3000, 3000, 3000, 3000, 3000, 3000, NA, NA, NA, NA, 3000, NA, 
NA, NA, 3000), total = c(7000, 7000, 7000, 7000, 1500, 1500, 
1500, 1500, 4000, 3000, 3000, 3000, 500, 500, 500, 500, 4500, 
500, 500, 500, 4500, 500, 1500, 1500, 1500, 3000, 3000, 4000, 
4000, 4500, 4500, 4500, 4500, 1500, 500, 500, 1500, 1500, 4000, 
4000, 4000, 4000, 0, 0, 0, 1500, 0, 0, 0, 0, 3000, 3000, 3000, 
0, 0, 0, 0, 0, 1500, 1500, 4500, 4500, 3000, 3000, 3500, 3500, 
3500, 3500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 7000, 7000, 4000, 4000, 3500, 
3500, 3000, 3000, 3000, 3000, 3000, 4000, 4000, 500, 500, 500, 
500, 6500, 3500, 500, 0, 3000), year = c("2015", "2016", "2017", 
"2018", "2015", "2016", "2017", "2018", "2015", "2016", "2017", 
"2018", "2015", "2016", "2017", "2018", "2015", "2015", "2016", 
"2017", "2015", "2018", "2016", "2017", "2018", "2015", "2016", 
"2017", "2018", "2015", "2016", "2017", "2018", "2015", "2018", 
"2016", "2015", "2017", "2015", "2016", "2017", "2018", "2016", 
"2017", "2018", "2018", "2015", "2016", "2017", "2018", "2015", 
"2016", "2017", "2018", "2015", "2016", "2017", "2018", "2015", 
"2016", "2017", "2018", "2016", "2017", "2015", "2016", "2017", 
"2018", "2015", "2016", "2017", "2018", "2016", "2017", "2018", 
"2015", "2016", "2017", "2018", "2015", "2016", "2017", "2018", 
"2015", "2018", "2015", "2016", "2017", "2018", "2015", "2016", 
"2018", "2015", "2016", "2017", "2018", "2016", "2017", "2015", 
"2016", "2017", "2018", "2016", "2017", "2018", "2015", "2016"
), serviceDivision = c("division1", "division1", "division1", 
"division1", "division2", "division2", "division2", "division2", 
"division1", "division1", "division1", "division1", "division2", 
"division2", "division2", "division2", "division1", "division2", 
"division2", "division2", "division2", "division2", "division2", 
"division2", "division2", "division3", "division3", "division3", 
"division3", "division1", "division1", "division1", "division1", 
"division2", "division2", "division2", "division2", "division2", 
"division1", "division1", "division1", "division1", "division1", 
"division1", "division1", NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "division2", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA), numFunders = c(4, 4, 4, 4, 2, 2, 2, 
2, 2, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 1, 2, 2, 2, 1, 1, 2, 
2, 3, 3, 3, 3, 2, 1, 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 0, 0, 0, 
0, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, 3, 2, 2, 
1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 3, 2, 1, 0, 1), multiFunder = c(TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, 
TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE
), provFunders = c(8, 8, 7, 7, 3, 3, 3, 3, 2, 3, 2, 3, 1, 1, 
1, 1, 5, 2, 2, 1, 2, 1, 3, 3, 3, 2, 2, 3, 3, 5, 5, 5, 5, 3, 1, 
1, 3, 3, 4, 3, 3, 4, 1, 1, 1, 3, 1, 1, 1, 1, 2, 2, 2, 1, 3, 2, 
2, 2, 3, 4, 4, 4, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 
3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 3, 1, 1, 1, 1, 3, 3, 
3, 4, 3, 3, 3, 5, 1, 1, 1), nonProvFunders = c(3, 4, 4, 4, 0, 
0, 0, 0, 1, 5, 3, 5, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 1, 1, 1, 2, 
4, 3, 3, 2, 2, 3, 3, 1, 0, 0, 0, 0, 3, 4, 4, 4, 0, 0, 0, 0, 0, 
0, 0, 0, 2, 2, 2, 0, 1, 0, 0, 0, 0, 0, 1, 1, 4, 3, 1, 1, 1, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 
3, 2, 4, 1, 1, 2, 1, 2, 2, 0, 0, 0, 1, 3, 3, 0, 0, 2), provFundedOnly = c(FALSE, 
FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 
FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, 
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 
FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, 
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE), provincialFunding = c(1500, 
1500, 1500, 1500, 1500, 1500, 1500, 1500, 1000, 0, 0, 0, 500, 
500, 500, 500, 1500, 500, 500, 500, 1500, 500, 1500, 1500, 1500, 
0, 0, 1000, 1000, 1500, 1500, 1500, 1500, 1500, 500, 500, 1500, 
1500, 1000, 1000, 1000, 1000, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 1500, 1500, 1500, 1500, 0, 0, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 1500, 1500, 1500, 1500, 500, 500, 0, 
0, 0, 0, 0, 1000, 1000, 500, 500, 500, 500, 1000, 1000, 500, 
0, 0), nonProvincialFunding = c(5500, 5500, 5500, 5500, 0, 0, 
0, 0, 3000, 3000, 3000, 3000, 0, 0, 0, 0, 3000, 0, 0, 0, 3000, 
0, 0, 0, 0, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 0, 
0, 0, 0, 0, 3000, 3000, 3000, 3000, 0, 0, 0, 0, 0, 0, 0, 0, 3000, 
3000, 3000, 0, 0, 0, 0, 0, 0, 0, 3000, 3000, 3000, 3000, 3000, 
3000, 3000, 3000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 5500, 5500, 2500, 2500, 3000, 3000, 3000, 3000, 3000, 3000, 
3000, 3000, 3000, 0, 0, 0, 0, 5500, 2500, 0, 0, 3000), agencySize = c("greater than $15M", 
"greater than $15M", "greater than $15M", "greater than $15M", 
"greater than $15M", "greater than $15M", "greater than $15M", 
"greater than $15M", "less than $1M", "$7M - $15M", "$7M - $15M", 
"$7M - $15M", "$1M - $2M", "$1M - $2M", "$1M - $2M", "$1M - $2M", 
"$2M - $4M", "less than $1M", "less than $1M", "less than $1M", 
"$2M - $4M", "$2M - $4M", "$4M - $7M", "$4M - $7M", "$4M - $7M", 
"$1M - $2M", "$1M - $2M", "$2M - $4M", "$2M - $4M", "$2M - $4M", 
"$2M - $4M", "$4M - $7M", "$4M - $7M", "$2M - $4M", "less than $1M", 
"$1M - $2M", "$2M - $4M", "$2M - $4M", "$2M - $4M", "$2M - $4M", 
"$4M - $7M", "$4M - $7M", "$1M - $2M", "$1M - $2M", "$1M - $2M", 
"less than $1M", "less than $1M", "less than $1M", "less than $1M", 
"less than $1M", "$1M - $2M", "$2M - $4M", "$2M - $4M", "$1M - $2M", 
"less than $1M", "less than $1M", "less than $1M", "less than $1M", 
"$4M - $7M", "$4M - $7M", "$4M - $7M", "$4M - $7M", "greater than $15M", 
"greater than $15M", "$2M - $4M", "$2M - $4M", "$2M - $4M", "$2M - $4M", 
"$1M - $2M", "$1M - $2M", "$1M - $2M", "$1M - $2M", "$2M - $4M", 
"$2M - $4M", "$2M - $4M", "less than $1M", "less than $1M", "less than $1M", 
"less than $1M", "less than $1M", "less than $1M", "$1M - $2M", 
"$1M - $2M", "$7M - $15M", "$7M - $15M", "greater than $15M", 
"greater than $15M", "greater than $15M", "greater than $15M", 
"$1M - $2M", "$1M - $2M", "$2M - $4M", "less than $1M", "less than $1M", 
"less than $1M", "less than $1M", "$1M - $2M", "$1M - $2M", "less than $1M", 
"less than $1M", "less than $1M", "less than $1M", "$2M - $4M", 
"$2M - $4M", "$2M - $4M", "$1M - $2M", "$1M - $2M"), funder1funded = c(TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 
FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE), funder13funded = c(TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, 
TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, 
FALSE), funder2funded = c(FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE), funder3funded = c(FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE), funder4funded = c(TRUE, TRUE, 
TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
TRUE, TRUE, FALSE, FALSE, FALSE), funder5funded = c(TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), sectorFunded = c("TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE"), totHolder = c(7000, 7000, 7000, 7000, 1500, 
1500, 1500, 1500, 4000, 3000, 3000, 3000, 500, 500, 500, 500, 
4500, 500, 500, 500, 4500, 500, 1500, 1500, 1500, 3000, 3000, 
4000, 4000, 4500, 4500, 4500, 4500, 1500, 500, 500, 1500, 1500, 
4000, 4000, 4000, 4000, 0, 0, 0, 1500, 0, 0, 0, 0, 3000, 3000, 
3000, 0, 0, 0, 0, 0, 1500, 1500, 4500, 4500, 3000, 3000, 3500, 
3500, 3500, 3500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 7000, 7000, 4000, 4000, 
3500, 3500, 3000, 3000, 3000, 3000, 3000, 4000, 4000, 500, 500, 
500, 500, 6500, 3500, 500, 0, 3000)), row.names = c(NA, -107L
), class = c("tbl_df", "tbl", "data.frame"))

Обратите внимание, что provincialFunding - это сумма спонсоров 1,2, а 3 и nonProvincialFunding - сумма спонсоров 4,5 и другие.

Предложение группировки, переданное функции для этого примера:

GRclauseSDregion <- c("year", "employerClass", "multiFunder", "serviceDivision", "healthRegion")

Есть несколько предложений группировки;

GRsectorProfile <- c("year", "employerClass", "multiFunder")
GRclass1SD <- c("year", "employerClass", "multiFunder", "serviceDivision")
GRsectorRegion <- c("year", "employerClass", "multiFunder", "healthRegion")
GRclass1SDregion <- c("year", "employerClass", "multiFunder", "serviceDivision", "healthRegion")
GRsectorAgencySize <- c("year", "employerClass", "multiFunder", "agencySize")
GRclass1AgencySize <- c("year","employerClass", "multiFunder", "agencySize")
GRclass1SDagencySize <- c("year", "employerClass", "multiFunder", "serviceDivision", "agencySize")
GRclass1SDregionAgencySize <- c("year", "employerClass", "multiFunder", "serviceDivision", "healthRegion", "agencySize")
GRnonCLASS1AregionAgencySize <- c("year", "employerClass", "multiFunder", "healthRegion", "agencySize")
GRclass1RegionAgencySize <- c("year", "employerClass", "multiFunder", "healthRegion", "agencySize")

Здесь у меня есть Получено:

# collapse function (funder)
collapsePassFunderArray <- function(df, funderTrueCol, fundingCol, groupClause, name) {
  funderTrueHolder <- enquo(funderTrueCol)
  fundingColHolder <- enquo(fundingCol)
  newDf <- df %>% 
    filter((!!funderTrueHolder) == TRUE) %>% 
    group_by(.dots = groupClause) %>% 
    summarise(funderName = name, 
              totFund = sum(total),
              minFunder = min(numFunders),
              maxFunder = max(numFunders),
              avgFunder = mean(numFunders, na.rm = TRUE),
              medianFunder = median(numFunders, na.rm = TRUE),
              provPerc = sum(provincialFunding)/sum(total),
              nonProvPerc = sum(nonProvincialFunding)/sum(total),
              funderPercProv = sum((!!fundingColHolder))/sum(provincialFunding),
              funderPercTot = sum((!!fundingColHolder))/sum(total),
              numAgencies = n_distinct(contactID),
              funders = simplify2array(apply(df[8:13], 1, 
                                            function(x)paste(names(df[6:11]) [which(!is.na(x))], collapse = " ")))
    )
}

Обратите внимание, что выбранные столбцы кадра данных [6:11] - это те столбцы, которые будут подвергаться проверке со стороны спонсоров. Со временем это может измениться, но я не возражаю вносить изменения вручную.

Следующий код выдает желаемый вывод при применении к полному набору данных (желаемый вывод - список разделителей, разделенных пробелами, в переменной funders ):

reproTable$funders <- simplify2array(apply(reproTable[6:11], 1, 
                                           function(x)paste(names(reproTable[8:13]) [which(!is.na(x))], collapse = " ")))

Я выполняю следующий вызов функции:

test1 <- collapsePassFunderArray(reproTable, funder1funded, funder1, GRclauseSDregion, "All")

, что приводит к следующей ошибке:

Error: Column `funders` must be length 1 (a summary value), not 107 

Вот требуемый вывод в предположении что мы используем условие группировки GRsectorRegion <- c ("year", "employeeerClass", "multiFunder", "healthRegion") согласно запросу пользователя @akrun: </p>

https://pastebin.com/1Z8vRLir

Извините, мне пришлось используйте pastebin для вставки нужного источника вывода, он превысил ограничение на число символов.

Спасибо тем, кто пытался это взломать. Я пытался адаптировать код, но столкнулся с проблемами, описанными в комментариях.

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Мы можем использовать group_by_at для передачи имен строковых столбцов вместе с pmap из purrr для paste элементов

library(dplyr)
library(stringr)
library(purrr)
collapsePassFunderArray <- function(df, funderTrueCol, 
                   fundingCol, groupClause, name) {
  funderTrueHolder <- enquo(funderTrueCol)
  fundingColHolder <- enquo(fundingCol)
  df %>% 
    filter((!!funderTrueHolder) == TRUE) %>% 
    mutate(funder = pmap_chr(select(., matches("^(funder\\d+$)|(^others$)")),
       ~ {x1 <- c(...)
         str_c(names(x1)[!is.na(x1)], collapse=" ")
         }))  %>%
    group_by_at(vars(intersect(groupClause, names(.)), 'funder')) %>%
    summarise(funderName = name, 
              totFund = sum(total),
              minFunder = min(numFunders),
              maxFunder = max(numFunders),
              avgFunder = mean(numFunders, na.rm = TRUE),
              medianFunder = median(numFunders, na.rm = TRUE),
              provPerc = sum(provincialFunding)/sum(total),
              nonProvPerc = sum(nonProvincialFunding)/sum(total),
              funderPercProv = sum((!!fundingColHolder))/sum(provincialFunding),
              funderPercTot = sum((!!fundingColHolder))/sum(total),
              numAgencies = n_distinct(contactID))




    }

-testing

test1 <- collapsePassFunderArray(reproTable, funder1funded, funder1, GRclauseSDregion, "All")
test1$funder
#[1] "funder1 funder3 funder5 others"  "funder1 funder3 funder4 funder5" "funder1 funder3 funder4 funder5"
#[4] "funder1 funder3 funder5"

test2 <- collapsePassFunderArray(reproTable, funder2funded, funder2, GRclauseSDregion, "All")
test2$funder
#[1] "funder2 funder4"        "funder2 funder4 others" "funder2 funder4 others"
testothers <- collapsePassFunderArray(reproTable, otherFunded, others, GRclauseSDregion, "All")
testothers$funder
#[1] "funder1 funder3 funder5 others" "funder2 funder4 others"         "funder2 funder4 others"
1 голос
/ 21 марта 2020

Обновление в 2020-04-01

"Дело в том, что мне нужно суммарное значение provvincialFunding, которое оно выплевывает, чтобы оно было суммой всех провинциальных; финансирование в рамках подмножества, установленного в групповом предложении. Поэтому, когда я запускаю это на верхних уровнях агрегации, например, для сектора в целом, финансирующее лицо, оно начинает давать мне неправильные цифры. Также, когда я беру общее из уравнения, я не могу выполнить это в целом по сектору. "

У меня был еще один удар по этому вопросу, основанный на ваших комментариях и результатах, предоставленных по вашей ссылке pastebin . Если это по-прежнему не отвечает на ваш вопрос, могу ли я попросить вас поделиться примерами «правильных» ответов для более широкого набора группирующих предложений, так как это, мы надеемся, упростило бы выяснение того, где / когда происходит сбой метода. Например, мне не ясно, каков ваш ожидаемый результат для «агрегация для всего сектора со стороны спонсора» .

Прежде чем показывать обновленный подход ниже, есть ряд из предостережений:

  • Кажется, что есть какое-то разъединение между данными, передаваемыми в вашем OP, и выводом, передаваемым через pastebin . В частности:
    • Кажется, что входные данные, используемые для генерации вывода, совместно используемого с помощью pastebin , несколько отличаются от того, что использовалось в вашем OP.
    • pastebin данные содержат столбец multiFunded в отличие от multiFunder согласно вашему OP
    • Данные pastebin включают столбец numFunder, хотя функция collapsePassFunderArray() в вашем OP
    • Ваш вывод pastebin не содержит столбец medianFunder в соответствии с функцией collapsePassFunderArray() в вашем OP
    • Значения в pastebin вывод для столбцов funderPercProv и funderPercTot смущает меня: я бы предположил, что funderPercProv должен представлять общее финансирование донором x как процент от общего провинциального финансирования в рамках пункта группировки . Однако, несмотря на то, что есть несколько случаев, когда, например, общий объем финансирования на others превышает общий объем провинциального финансирования в рамках вашего примера группировки, значение funderPercProv в ваших данных для вставки никогда не превышает 1. Это не кажется прямо мне, но, возможно, я что-то упустил. Точно так же значения funderPercTot в ваших данных pastebin не соответствуют определению общего финансирования спонсором x как процента от общего финансирования в пункте группировки, Например, если вы посмотрите на данные из вашего OP, для которых действует следующий фильтр: filter(year == 2015 & employerClass == 'class1' & multiFunder == F & healthRegion == 'Region3'), то можно ясно увидеть, что финансирование на others составляет 3000/3500 = 0,8571429 от общего финансирования в рамках условия группировки ("year", "employerClass", "multiFunder", "healthRegion"). Тем не менее, ваш вывод команды pastebin сообщает об этом значении как 0,14285714.

Эти проблемы очень затрудняют проверку того, действительно ли следующее дает вам то, что вам нужно. Тем не менее, здесь надеемся, что это так. Я предположил, что вышеупомянутые определения для funderPercProv и funderPercTot - это то, что на самом деле желательно.

# load required libraries
library(tidyverse)

# NB: define original input data as per OP and store as object reproTable

# first convert data into long format
reproTable_long <- reproTable %>%
  select(-totHolder) %>%
  pivot_longer(
    cols = matches(
      '^funder\\d{1,}$|^others$|^total$|^provincialFunding$|nonProvincialFunding'
    ),
    names_to = 'funder'
  )

 # define function of interest 
collapsePassFunderArray <- function(df, FunderVal, groupClause, name) {
  reproTable_long %>% 
    group_by(.dots = GRsectorRegion) %>% 
    filter(sum(value[funder == FunderVal], na.rm = T) > 0) %>%
    summarise(
      funderName = name,
      totFund = sum(value[funder == 'total'], na.rm = T),
      minFunder = min(numFunders, na.rm = T),
      maxFunder = max(numFunders, na.rm = T),
      avgFunder = mean(numFunders, na.rm = TRUE),
      medianFunder = median(numFunders, na.rm = TRUE),
      provPerc = sum(value[funder == 'provincialFunding'], na.rm = T) / 
        sum(value[funder == 'total'], na.rm = T),
      nonProvPerc = sum(value[funder == 'nonProvincialFunding'], na.rm = T) / 
        sum(value[funder == 'total'], na.rm = T),
      funderPercProv = sum(value[funder == FunderVal], na.rm = T) / 
        sum(value[funder == 'provincialFunding'], na.rm = T),
      funderPercTot = sum(value[funder == FunderVal], na.rm = T) / 
        sum(value[funder == 'total'], na.rm = T),
      numAgencies = n_distinct(contactID),
      funders = funder[!is.na(value) & !funder %in% c('total', 'provincialFunding', 'nonProvincialFunding')] %>% 
        unique() %>% 
        paste( collapse = " ")
    ) %>% 
    ungroup()
} 


 # define grouping clauses
GRclauseSDregion <- c("year", "employerClass", "multiFunder", "division", "healthRegion")
GRsectorProfile <- c("year", "employerClass", "multiFunder")
GRcsseaSD <- c("year", "employerClass", "multiFunder", "serviceDivision")
GRsectorRegion <- c("year", "employerClass", "multiFunder", "healthRegion")
GRcsseaSDregion <- c("year", "employerClass", "multiFunder", "serviceDivision", "healthRegion")
GRsectorAgencySize <- c("year", "employerClass", "multiFunder", "agencySize")
GRcsseaAgencySize <- c("year","employerClass", "multiFunder", "agencySize")
GRcsseaSDagencySize <- c("year", "employerClass", "multiFunder", "serviceDivision", "agencySize")
GRcsseaSDregionAgencySize <- c("year", "employerClass", "multiFunder", "serviceDivision", "healthRegion", "agencySize")
GRnonCSSEAregionAgencySize <- c("year", "employerClass", "multiFunder", "healthRegion", "agencySize")
GRcsseaRegionAgencySize <- c("year", "employerClass", "multiFunder", "healthRegion", "agencySize")

# test a few clauses for funder1, funder2, etc
others_GRclauseSDregion <- collapsePassFunderArray(reproTable_long, 'others', GRclauseSDregion, name = 'All')
funder1_GRcsseaSD <- collapsePassFunderArray(reproTable_long, 'funder1', GRcsseaSD, name = 'All')
funder2_GRcsseaAgencySize <- collapsePassFunderArray(reproTable_long, 'funder2', GRcsseaAgencySize, name = 'All')
funder5_GRnonCSSEAregionAgencySize <- collapsePassFunderArray(reproTable_long, 'funder5', GRnonCSSEAregionAgencySize, name = 'All')

Оригинальный ответ

Спасибо Вы за осторожное объяснение и solid представительство!

Я просто не могу обернуть голову вокруг того, что я сделал бы здесь, чтобы получить желаемый результат. Я думаю, что я должен сделать кавычки для функции внутри функции и прочитал и перечитал vignetter при программировании в dplyr несколько раз, но я просто не понимаю.

Вы уже выделили что следующий сегмент вашей collapsePassFunderArray функции массива прекрасно работает с несгруппированными данными:

funders = simplify2array(apply(df[8:13], 1,
                               function(x)
                                 paste(names(df[8:13]) [which(!is.na(x))], collapse = " "))

Я подозреваю, что (хотя я не уверен на 100%), в текущей форме эта функция работает на исходные, нефильтрованные и разгруппированные входные данные df, а не отфильтрованные и сгруппированные данные, которые вы передаете в свой summarise вызов внутри collapsePassFunderArray(). Если это действительно так, то полученная ошибка имеет смысл: функция все еще работает с исходными 7-строчными входными данными и поэтому попытается вернуть 7-ми строк.

Что касается получения желаемых результатов: я попытался сделать это, применив несколько иной, но, надеюсь, все же полезный подход. Ниже я сначала расскажу о представлении, а затем попытаюсь объяснить его далее:

# load required libraries
library(tidyverse)

# define data using the data pasted in the original post

# define function of interest 
collapsePassFunderArray <- function(df, FunderVal, groupClause) {

  df %>% 
    pivot_longer(cols = matches('^funder\\d{1,}$|^others$|^total$'), names_to = 'funder') %>% 
    filter(funder != 'total')  %>% 
    group_by(.dots = groupClause) %>% 
    filter(sum(value[funder == FunderVal], na.rm = T) > 0) %>% 
    summarise(
      funderName = first(name),
      totFund = sum(value, na.rm = T),
      minFunder = min(numFunders),
      maxFunder = max(numFunders),
      avgFunder = mean(numFunders, na.rm = TRUE),
      medianFunder = median(numFunders, na.rm = TRUE),
      provPerc = first(provincialFunding) / totFund,
      nonProvPerc = first(nonProvincialFunding) / totFund,
      funderPercProv = sum(value[funder == FunderVal]) / first(provincialFunding),
      funderPercTot = sum(value[funder == FunderVal]) / totFund,
      numAgencies = n_distinct(contactID),
      funders = paste(funder[!is.na(value)], collapse = " ")
    )
}

# define grouping clause
GRclauseSDregion <- c("year", "employerClass", "multiFunder", "division", "healthRegion")

# test for funder1, funder2, etc
test1 <- collapsePassFunderArray(reproTable, 'funder1', GRclauseSDregion)
test2 <- collapsePassFunderArray(reproTable, 'funder2', GRclauseSDregion)
testothers <- collapsePassFunderArray(reproTable, 'others', GRclauseSDregion)

Вот моя попытка объяснить функцию:

  • Взять входные данные и сначала изменить их от широкого до длинного (мне гораздо, гораздо проще работать с данными в длинном формате). Код для преобразования в long является достаточно гибким, поскольку он использует сопоставление регулярных выражений, а не позиционное нацеливание, чтобы идентифицировать соответствующие столбцы funder . Однако обратите внимание, что этот код предполагает, что ваши столбцы funder всегда будут называться funder*, где * представляет числовой суффикс или others. Если это так, код должен иметь возможность обрабатывать произвольное количество столбцов спонсора. В качестве альтернативы, вы можете просто адаптировать используемое регулярное выражение.
  • Затем удалите все экземпляры, где новый столбец funder имеет значение total (всегда можно воссоздать это значение на основе других строк в данные)
  • Затем примените выбранное условие группировки
  • . Сгруппировав данные, мы теперь используем фильтр, чтобы гарантировать, что мы сохраняем данные только для всех групп, для которых общий объем финансирования предоставлен спонсором. вопрос больше нуля
  • Далее мы переходим к вызову summarise. Обратите внимание, что большинство изменений вашей исходной функции, которые были сделаны здесь, просто предназначены для учета того факта, что данные были повернуты от широкой к длинной. Единственное существенное отличие состоит в том, как я создаю свернутую строку спонсоров. В частности, я просто подставляю все строки, чтобы сохранить только тех спонсоров, которые внесли вклад не NA. Затем я сворачиваю их в разделенную пробелами символьную строку.

Мое тестирование показывает, что результаты совпадают с тем, что сгенерировано кодом, который вы указали в исходном посте. Тем не менее, я понимаю, что я существенно изменил способ работы функции и, что более важно, способ ее вызова. Возможно, это не то, что вы ищете, но я надеюсь, что это на правильном пути!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...