Динамически генерировать имена столбцов - PullRequest
0 голосов
/ 31 августа 2018

Я хотел бы динамически генерировать столбцы на основе ширины оператора вырезания.

Как я могу динамически генерировать AGE1 в AGEn, как в примере ниже?

library(dplyr)
df <- data.frame(AGE = 10:19, NUM = rnorm(n=10))

# for 2
num_by <- 2
df_out2 <- df %>%
  mutate(AGEGROUP = cut(AGE, breaks = seq(10, 20, by = num_by), right = F)) %>%
  group_by(AGEGROUP) %>%
  summarise(SUM.NUM = sum(NUM))%>%
  mutate(AGELOW = as.numeric(substr(as.character(AGEGROUP), 2, 3)),
         AGE1 = AGELOW + 1)%>%
  select(-AGEGROUP) %>%
  gather(AGE, AGELOW:AGE1, -c(SUM.NUM))

# for 3
num_by <- 3
df_out3 <- df %>%
  mutate(AGEGROUP = cut(AGE, breaks = seq(10, 20, by = num_by), right = F)) %>%
  group_by(AGEGROUP) %>%
  summarise(SUM.NUM = sum(NUM))%>%
  mutate(AGELOW = as.numeric(substr(as.character(AGEGROUP), 2, 3)),
         # generate AGEn from 1:(num_by-1)
         AGE1 = AGELOW + 1,
         AGE2 = AGELOW + 2)%>%
  select(-AGEGROUP) %>%
  gather(AGE, AGELOW:AGE2, -c(SUM.NUM))

1 Ответ

0 голосов
/ 01 сентября 2018

создать функцию. Это содержит решение для цикла

cut_function <- function(df, num_cuts) {
  num_by <- num_cuts
  df_out <- df %>%
  mutate(AGEGROUP = cut(AGE, breaks = seq(10, 20, by = num_by), right = F)) %>%
  group_by(AGEGROUP) %>%
  summarise(SUM.NUM = sum(NUM)) %>%
  mutate(AGELOW = as.numeric(substr(as.character(AGEGROUP), 2, 3)))
         # generate AGEn from 1:(num_by-1)

for(i in 2:num_by-1) { 

# this is the core of the function 
# it assigns a new column based on the index i
# i depends on the length of your num_by

 df_out[[paste0('AGE',i)]] <- df_out$AGELOW + i
 df_out
}
 df_out %>% select(-AGEGROUP) %>% 
   gather(AGE, value, AGELOW:paste0('AGE',num_by-1), -c(SUM.NUM))
}

Test

cut_function(df,2)
    # A tibble: 10 x 3
   SUM.NUM AGE    value
     <dbl> <chr>  <dbl>
 1   0.311 AGELOW    10
 2  -3.43  AGELOW    12
 3  -0.237 AGELOW    14
 4   1.82  AGELOW    16
 5   0.332 AGELOW    18
 6   0.311 AGE1      11
 7  -3.43  AGE1      13
 8  -0.237 AGE1      15
 9   1.82  AGE1      17
10   0.332 AGE1      19

cut_function(df,3)
    # A tibble: 12 x 3
   SUM.NUM AGE    value
     <dbl> <chr>  <dbl>
 1  -2.56  AGELOW    10
 2  -0.799 AGELOW    13
 3   1.58  AGELOW    16
 4   0.569 AGELOW    NA
 5  -2.56  AGE1      11
 6  -0.799 AGE1      14
 7   1.58  AGE1      17
 8   0.569 AGE1      NA
 9  -2.56  AGE2      12
10  -0.799 AGE2      15
11   1.58  AGE2      18
12   0.569 AGE2      NA

Однако

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

df %>%
  mutate(AGEGROUP = cut(AGE, breaks = seq(10, 20, by = num_by), right = F)) %>%
  group_by(AGEGROUP) %>%
  mutate(SUM.NUM = sum(NUM)) 

#gives basically exactly the same output as your df_out2

# A tibble: 10 x 4
# Groups:   AGEGROUP [5]
     AGE     NUM AGEGROUP SUM.NUM
   <int>   <dbl> <fct>      <dbl>
 1    10  0.463  [10,12)    0.311
 2    11 -0.151  [10,12)    0.311
 3    12 -2.87   [12,14)   -3.43 
 4    13 -0.562  [12,14)   -3.43 
 5    14 -0.276  [14,16)   -0.237
 6    15  0.0392 [14,16)   -0.237
 7    16  1.99   [16,18)    1.82 
 8    17 -0.168  [16,18)    1.82 
 9    18 -0.236  [18,20)    0.332
10    19  0.569  [18,20)    0.332

Вы можете создать функцию, как указано выше без необходимости цикла for .

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