R / purrr: условное перераспределение столбчатых данных с использованием карты - PullRequest
1 голос
/ 21 марта 2019

Я действительно заинтересовался изучением (и в конечном итоге освоением) пакета purrr.Но, несмотря на то, что я просмотрел довольно много уроков ( 1 , 2 , 3 , 4 ), я с трудом понимаю:-и использовать - purrr::map (и функциональное программирование в целом).

Мой тестовый сценарий - это фрейм данных, содержащий два столбца, как показано ниже:

df <- data.frame("ColChars" = c("A", "B", "C", "A", "B", "C"), "ColNums" = c(1:6))
df
#   ColChars ColNums
# 1        A       1
# 2        B       2
# 3        C       3
# 4        A       4
# 5        B       5
# 6        C       6

What I 'я хотел бы использовать map (или map_df?) для перестановки данных в ColNums следующим образом:

df
#   ColChars ColNums
# 1        A    1, 4
# 2        B    2, 5
# 3        C    3, 6

Я знаю, что я могу легко сделать это с помощью цикла for:

df <- data.frame("ColChars" = c("A", "B", "C", "A", "B", "C"), "ColNums" = c(1:6))
newdf <- data.frame(character(), character())
GrpVar <- unique(df$ColChars)
for(i in 1:length(GrpVar)){
  TmpColChars <- GrpVar[i]
  TmpColNums <- paste(df$ColNums[df$ColChars==GrpVar[i]], collapse=",")
  tmpdf <- data.frame(TmpColChars, TmpColNums, stringsAsFactors = FALSE)
  newdf <- rbind(newdf, tmpdf)
}
(newdf <- setNames(newdf, names(df)))

#   ColChars ColNums
# 1        A     1,4
# 2        B     2,5
# 3        C     3,6

Как бы я реализовал это, используя map?(в качестве примера) Или такая операция не подходит для подхода map?Я предполагаю, что моя проблема на самом деле заключается в серьезном непонимании (+ непонимании) таких методов, как lapply, и я надеюсь, что ответы на этот вопрос позволят мне исправить это.

1 Ответ

2 голосов
/ 21 марта 2019

Короткий ответ

Нет необходимости map здесь:

df %>% 
   group_by(ColChars) %>% 
   summarise(ColNums = paste(ColNums, collapse = ", "))

Ответ с помощью map

Вы можете использовать map довольно сложным способом:

library(dplyr)
df %>% 
   group_by(ColChars) %>% 
   tidyr::nest() %>% 
   mutate(ColNums = map_chr(data, ~ paste(.$ColNums, collapse = ","))) %>% 
   select(-data)

# # A tibble: 3 x 2
#   ColChars ColNums
#   <fct>    <chr>  
# 1 A        1,4    
# 2 B        2,5    
# 3 C        3,6 

Объяснение

  1. group_by: вы хотите сделать остальную часть трубы за ColChar
  2. nest: вы суммируете не группирующие переменные в tibble, который становится новым столбцом data в вашем результате (data - это столбец, который содержит 3 tibbles)
  3. теперь вы map_chr просматриваете каждый элемент данных (который является tibble), и для каждого tibble вы извлекаете столбец ColNums и вставляете его вместе.

Примечание вам нужен символьный вектор, а не список, поэтому вы используете map_chr вместо map


Лучшее объяснение того, как использовать map

Согласно комментариям, это не лучший пример использования map, поскольку это может быть лучше решено с помощью group_by и summarise. Следовательно, вот более содержательный пример, объясняющий преимущества map:

library(tidyverse)
set.seed(1)
d <- data.frame(grp = rep(LETTERS[1:3], each = 100),
                x   = rnorm(300),
                y   = rnorm(300))
(d <- d %>% 
  group_by(grp) %>%
  summarise(mod = list(lm(y~x))))
# # A tibble: 3 x 2
#   grp   mod     
#   <fct> <list>  
# 1 A     <S3: lm>
# 2 B     <S3: lm>
# 3 C     <S3: lm> 

Теперь предположим, что вы хотите получить скорректированный квадрат R для каждой модели. Вы можете попробовать:

d %>% mutate(ar = summary(mod)$adj.r.squared)
Error in summary(mod)$adj.r.squared : 
  $ operator is invalid for atomic vectors

Однако это не работает, б / с dplyr передает весь столбец mod в summary, и вы фактически делаете summary(d$mod), что не то, что вы хотите.

Здесь map становится удобным:

d %>% mutate(ar = map_dbl(mod, ~ summary(.)$adj.r.squared))
# # A tibble: 3 x 3
#   grp   mod            ar
#   <fct> <list>      <dbl>
# 1 A     <S3: lm> -0.00763
# 2 B     <S3: lm>  0.00826
# 3 C     <S3: lm> -0.00843

Теперь вы просматриваете каждый элемент mod и извлекаете скорректированный квадрат r из сводки.

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