2

I have a function from a package(tidycensus), that I want to use it through the piping and mutate. I have created this simple mockup to show the situation.

library(tidycensus)

tt <- as_data_frame(matrix(1:36, ncol = 6))
colnames(tt) <- c("A", "B", "C", "D", "E", "F")
tt2 <- tt %>% mutate(moe=moe_prop(.[,"A"],.[,"C"], .[,"D"],.[,"B"]))

The final result wraps the results into lists (all equal with the calculated values in each) and puts them in each place of moe column, as you can see below. Obviously, I want a vector as a result which fills column moe

> tt2
# A tibble: 6 x 7
      A     B     C     D     E     F    moe      
    <int> <int> <int> <int> <int> <int> <list>   
1     1     7    13    19    25    31 <dbl [6]>
2     2     8    14    20    26    32 <dbl [6]>
3     3     9    15    21    27    33 <dbl [6]>
4     4    10    16    22    28    34 <dbl [6]>
5     5    11    17    23    29    35 <dbl [6]>
6     6    12    18    24    30    36 <dbl [6]>

I know that using [,"Column_name] format returns list. Therefore, I tried to add as.vector beofore each of the input variables into the function. still same results. I wonder what I am missing here.

BobbyF
  • 431
  • 1
  • 7
  • 19

2 Answers2

1

Based on the input dataset, assuming that we only need one value per each row by doing the moe_prop on each row, convert the column names to symbols and then do an evaluation (!!!)

tt %>% 
  mutate(moe = moe_prop(!!! rlang::syms(names(.)[c(1, 3, 4, 2)])))
# A tibble: 6 x 7
#      A     B     C     D     E     F   moe
#  <int> <int> <int> <int> <int> <int> <dbl>
#1     1     7    13    19    25    31  1.46
#2     2     8    14    20    26    32  1.43
#3     3     9    15    21    27    33  1.39
#4     4    10    16    22    28    34  1.37
#5     5    11    17    23    29    35  1.34
#6     6    12    18    24    30    36  1.31

It is similar to calling

tt %>%
   mutate(moe = moe_prop(!!! rlang::syms(c("A", "C", "D", "B"))))

Or do a rowwise() operation

tt %>%
    rowwise %>% 
    mutate(moe = moe_prop(A, C, D, B))

By checking the row values individually

moe_prop(1, 13, 19, 7)
#[1] 1.460951

moe_prop(2, 14, 20, 8)
#[1] 1.426237
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thank you very much. This is really great. But what if I want to give the names of the columns directly? In my actual problem the names of the input columns are different in different runs and since their numbers might also be different, therefore column indexes may change, so each time I have a set of column names. – BobbyF Sep 12 '18 at 16:37
  • 1
    @BobbyF, added another option which would be a bit slow. In the first case, we are directly converting the column names. Only thing is that it was easier for me to do it. Instead you can do `tt %>% mutate(moe = moe_prop(!!! rlang::syms(c("A", "C", "D", "B")))` – akrun Sep 12 '18 at 16:38
  • 1
    Oh. that's right!! basic R I think. Totally forgot. Thank you very much. – BobbyF Sep 12 '18 at 16:43
1

You can use unnest()

library(dplyr)
library(tidyr)
library(tidycensus)

tt <- as_data_frame(matrix(1:36, ncol = 6))
colnames(tt) <- c("A", "B", "C", "D", "E", "F")
tt2 <- tt %>% 
  mutate(moe = moe_prop(.[, "A"], .[, "C"], .[, "D"], .[, "B"]))

tt2 %>%
  unnest()
#> # A tibble: 36 x 7
#>        A     B     C     D     E     F   moe
#>    <int> <int> <int> <int> <int> <int> <dbl>
#>  1     1     7    13    19    25    31  1.46
#>  2     1     7    13    19    25    31  1.43
#>  3     1     7    13    19    25    31  1.39
#>  4     1     7    13    19    25    31  1.37
#>  5     1     7    13    19    25    31  1.34
#>  6     1     7    13    19    25    31  1.31
#>  7     2     8    14    20    26    32  1.46
#>  8     2     8    14    20    26    32  1.43
#>  9     2     8    14    20    26    32  1.39
#> 10     2     8    14    20    26    32  1.37
#> # ... with 26 more rows

Created on 2018-09-12 by the reprex package (v0.2.0.9000).

Tung
  • 26,371
  • 7
  • 91
  • 115