Применить формулу к ряду переменных на основе части их имени - PullRequest
0 голосов
/ 06 марта 2020

У меня есть большие наборы данных, содержащие ~ 100 строк и +1000 столбцов. Некоторые из моих участников (строки) допустили ошибки в данных, введенных в некоторые переменные (столбцы), и я хотел бы исправить их автоматически.

Вот воспроизводимый пример с небольшим количеством строк и столбцов:

d <- tibble(nb = c(33, 54, 72),
            C1_1_66 = c(160, 7, 72),
            C1_1_77 = c(270, 18, 25),
            C1_1_88 = c(120, 5, 46),
            C1_1_99 = c(87, NA, NA),
            C1_2_66 = c(NA, 1, NA),
            C1_2_77 = c(NA, 45, NA),
            C1_2_88 = c(NA, NA, 77),
            C1_2_99 = c(2, NA, NA),
            C2_1_66 = c(120, NA, 90),
            C2_1_77 = c(170, NA, 102),
            C2_1_88 = c(120, NA, NA),
            C2_1_99 = c(230, NA, NA))
# A tibble: 3 x 13
     nb C1_1_66 C1_1_77 C1_1_88 C1_1_99 C1_2_66 C1_2_77 C1_2_88 C1_2_99 C2_1_66 C2_1_77 C2_1_88 C2_1_99
  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1    33     160     270     120      87      NA      NA      NA       2     120     170     120     230
2    54       7      18       5      NA       1      45      NA      NA      NA      NA      NA      NA
3    72      72      25      46      NA      NA      NA      77      NA      90     102      NA      NA

По сути, мне нужно следующее:

d <- d %>%
  mutate(C1_1_99 = C1_1_88 + C1_1_99, C1_1_88 = NA)

# A tibble: 3 x 13
     nb C1_1_66 C1_1_77 C1_1_88 C1_1_99 C1_2_66 C1_2_77 C1_2_88 C1_2_99 C2_1_66 C2_1_77 C2_1_88 C2_1_99
  <dbl>   <dbl>   <dbl> <lgl>     <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1    33     160     270 NA          207      NA      NA      NA       2     120     170     120     230
2    54       7      18 NA           NA       1      45      NA      NA      NA      NA      NA      NA
3    72      72      25 NA           NA      NA      NA      77      NA      90     102      NA      NA
> 

т.е. удалить содержимое из столбцов, заканчивающихся на _88, и добавить его в соответствующие столбцы, заканчивающиеся на _99, и удалить содержимое из переменные _88. Важно, чтобы каждый _88 был добавлен к соответствующему _99 (например, после кодирования в C1_1, C1_2, C1_3, C2_1, C2_2 и т. Д. c ... вплоть до C17). Но я хочу, чтобы это автоматически применялось ко всем переменным, заканчивающимся _88 и _99 . Это не большая проблема, что столбцы _88 установлены в NA во всех строках (я работаю над подмножеством фрейма данных, который содержит только участников, которые допустили ошибки с переменными _88), хотя это не очень элегантно.

Не уверен, как подойти к этому. Я пытался что-то вроде этого, но безуспешно:

f88 <- function(df, n){
  varname <- paste('C[0-9]_[0-9]_99')
  df %>%
    mutate(!!varname := 'C[0-9]_[0-9]_88' + 'C[0-9]_[0-9]_99')
}

for(i in 2:13) {
  unknown_t <- f88(df=d, n=i)
}

Есть идеи? Большое спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 06 марта 2020
Подход

A tidyverse будет превращать его в длинную форму, затем добавлять столбцы, а затем снова преобразовывать его в широкую форму.

d %>%
  pivot_longer(-nb,
               names_pattern = "(.+)(\\d{2})",
               names_to = c("prefix", ".value")) %>% 
  mutate(`99` = `88` + `99`,
         `88` = NA) %>% 
  pivot_wider(names_from = "prefix",
              values_from = c("66", "77", "88", "99"),
              names_sep = "-") %>% 
  setNames(nm = sub("(.*)-(.*)", "\\2\\1", names(.))) # repair the names
0 голосов
/ 06 марта 2020

Вы можете использовать индексные векторы и применять rowSums, используя Map.

# create index vectors
id.99 <- grep("_99", names(d))
id.88 <- grep("_88", names(d))

d[id.99] <- Map(function(x, y) rowSums(cbind(x, y), na.rm=TRUE), d[id.88], d[id.99])
d <- d[-id.88]  # drop "88" columns
#   nb C1_1_66 C1_1_77 C1_1_99 C1_2_66 C1_2_77 C1_2_99 C2_1_66 C2_1_77 C2_1_99
# 1 33     160     270     207      NA      NA       2     120     170     350
# 2 54       7      18       5       1      45       0      NA      NA       0
# 3 72      72      25      46      NA      NA      77      90     102       0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...