Имена динамических переменных с использованием функции изменения SE

Я не знаю, как разделить динамические переменные на группы внутри цикла for.

df - это фрейм данных, содержащий clm_april - clm_sept переменные, которые равны double. Также я хотел бы присвоить новым столбцам другие имена.

Группы, которые разные для каждого месяца, выглядят так:

> groups_april
 [1] "0"       "500"     "1000"    "1500"    "2000"    "3500"   
 [7] "4500"    "5000"    "9500"    "2000000"

Следующее не работает:

vector <- c("april", "may", "june", "july", "aug", "sept")

for (i in vector) {
  varname <- paste0("clm_", i)
  df <- df %>%
    mutate_(.dots = 
              cut(list(varname),
                  breaks = groups[i],
                  include.lowest = T,
                  dig.lab = 10))
}

Я также пробовал:

for (i in vector) {
  varname <- paste0("clm_", i)
  df <- df %>%
    mutate_(.dots = interp(~cut(list(varname),
                           breaks = groups[i],
                           include.lowest = T,
                           dig.lab = 10,  varname=as.name(varname))))
}

R выдает следующую ошибку:

Error in mutate_impl(.data, dots) : 
  Evaluation error: 'x' must be numeric.

Вы можете помочь мне решить эту проблему?

РЕДАКТИРОВАТЬ:

# A tibble: 10 x 6
   clm_april clm_may clm_june clm_july clm_aug clm_sept
       <dbl>   <dbl>    <dbl>    <dbl>   <dbl>    <dbl>
 1         0       0        0        0     689        0
 2      2000       0     1000     1000    1000        0
 3      5000    1000     1000     1000    1500     1518
 4      1000    1069     1100     1200    2019     2000
 5       679     689     9000    10000   36681     2000
 6       800    1000     1000      657    1815     2500

person Luka    schedule 27.02.2018    source источник
comment
попробуйте привести часть ваших данных в качестве примера, используя dput () или head () и вставив результат.   -  person denis    schedule 27.02.2018
comment
Обращаясь за помощью, вы должны указать простой воспроизводимый пример с образцом ввода и желаемым выводом, которые можно использовать для тестирования и проверки возможных решений   -  person MrFlick    schedule 27.02.2018
comment
Редактировал вопрос. Во всяком случае, я думаю, что уже включил всю необходимую вам информацию. Если тебе нужно что-то еще, просто скажи мне. Спасибо   -  person Luka    schedule 27.02.2018
comment
Ты прав. Я забыл упомянуть, что группы разные для каждого месяца. Также я хотел бы указать другие имена для этих новых добавленных столбцов. Редактировал вопрос.   -  person Luka    schedule 27.02.2018
comment
Я единственный человек, который не очень разбирается в этом вопросе ?? Я чувствую себя очень глупо :(   -  person tjebo    schedule 28.02.2018
comment
Возможно, это выглядит немного запутанным ... Я просто хочу выполнить изменение в цикле for (добавить новые столбцы с новыми именами, чтобы существующие столбцы были разделены на группы), но проблема в том, что параметр breaks в функция вырезания различна для каждого столбца (clm_april, clm_may ...). Я могу идти месяц за месяцем и вносить изменения (df %>% mutate(clm_new_x = cut(clm_x, breaks = group_x...))), но я хочу сделать код короче и написать более простой код, который будет проходить все месяцы, используя цикл for.   -  person Luka    schedule 28.02.2018


Ответы (1)


Один из вариантов - использовать map2_df из purrr пакета. map2_df позволит использовать данные по столбцам фактического data.frame. А также передайте имя столбца. Пользовательская функция find_breaks использует имя столбца для поиска соответствующего breaks, а затем вызывает cut.

Suppose different Groups are defined for each month is defined as:

groups_april <- c("0", "500", "1000",  "1500", "2000", "3500", "4500", "5000", "9500", "2000000")
groups_may <- c("0", "500", "1000",  "1500", "2000", "3500", "4500", "5000", "9500", "1000000")
groups_june <- c("0", "500", "1000",  "1500", "2000", "3500", "4500", "5000", "20000", "2000000")
groups_july <- c("0", "500", "1000",  "1500", "2000", "3500", "4500", "7000", "9500", "2000000")
groups_aug <- c("0", "500", "1000",  "1500", "2000", "3500", "4500", "6000", "9500", "2000000")
groups_sept <- c("0", "500", "1000",  "1500", "2000", "3500", "4500", "5000", "9500", "20000")


#Lets create a data.frame for Groups:
groups_df <- data.frame(groups_april, groups_may, groups_june, groups_july,
       groups_aug, groups_sept, stringsAsFactors = FALSE)


# Create a function to find breaks and apply cut
find_breaks <- function(x, y){
  #get the corresponding column name
  breaks_group_col <- grep(gsub("clm_", "", y), names(groups_df), value = TRUE)

  #apply cut using corresponding column from groups_df
  cut(x, breaks = groups_df[,breaks_group_col], include.lowest = TRUE, dig.lab = 10)
}

library(purrr)

# Pass df and column names of df to map2. 
map2_df(df, grep("clm_*", names(df), value = TRUE), function(.x, .y) find_breaks(.x, .y))

#Result
  clm_april   clm_may     clm_june     clm_july       clm_aug        clm_sept   
  <fctr>      <fctr>      <fctr>       <fctr>         <fctr>         <fctr>     
1 [0,500]     [0,500]     [0,500]      [0,500]        (500,1000]     [0,500]    
2 (1500,2000] [0,500]     (500,1000]   (500,1000]     (500,1000]     [0,500]    
3 (4500,5000] (500,1000]  (500,1000]   (500,1000]     (1000,1500]    (1500,2000]
4 (500,1000]  (1000,1500] (1000,1500]  (1000,1500]    (2000,3500]    (1500,2000]
5 (500,1000]  (500,1000]  (5000,20000] (9500,2000000] (9500,2000000] (1500,2000]
6 (500,1000]  (500,1000]  (500,1000]   (500,1000]     (1500,2000]    (2000,3500]

Данные

df <- read.table(text = "clm_april clm_may clm_june clm_july clm_aug clm_sept
1         0       0        0        0     689        0
2      2000       0     1000     1000    1000        0
3      5000    1000     1000     1000    1500     1518
4      1000    1069     1100     1200    2019     2000
5       679     689     9000    10000   36681     2000
6       800    1000     1000      657    1815     2500", header = T, stringsAsFactors = F)
person MKR    schedule 02.03.2018