Работа с переменными в функции в R - PullRequest
1 голос
/ 27 января 2020

Я пытаюсь создать функцию для запуска хи-квадрат, где мне нужно сгруппировать по нескольким группам. Однако, хотя метод работает, когда он не является функцией, у меня возникают проблемы с превращением в функцию. Поскольку я буду повторять процедуру несколько раз, кажется, что это стоит сделать, но я просто не могу заставить функцию распознавать переменную "z" и всегда получать предупреждение "Неизвестный или неинициализированный столбец".

Пример ниже.

library(tidyverse)
library(datasets)

#data
data(iris)
df<-iris%>%
  gather(Type, value, -Species)%>%
  separate(Type, c("type", "attribute"), sep="[.]")

#functions------------
frequency<-function(data, x, y, z){
  x <- enquo(x)
  y <- enquo(y)
  z <- enquo(z)

  data%>%
    filter(!is.na(!!x), !is.na(!!y), !is.na(!!z))%>%
    count(!!x, !!y, !!z)
}

group_chi<-function(data, x, y, z){
  x <- enquo(x)
  y <- enquo(y)

  data %>%
    group_by(!! x) %>%
    nest() %>%
    mutate(M = map(data, function(dat){
      dat2 <- dat %>% spread(!! y, n)
      M <- as.matrix(dat2[, -1])
      row.names(M) <- dat2$'z' #I've done it like this becasue z <- enquo(z) and dat2$!!z doesn't work. jsut having it a z doesnt work either
      return(M)
    }))%>%
    mutate(pvalue = map_dbl(M, ~chisq.test(.x)$p.value)) %>%
    select(-data, -M) %>%
    ungroup()
}

#aplying them--------------------

test<-frequency(df, type, Species, attribute)
chi_test<-group_chi(test,  type, Species, attribute)#brings up warning
#> Warning: Unknown or uninitialised column: 'z'.

#> Warning: Unknown or uninitialised column: 'z'.

#test without the function=no warning. 
No_function<-test %>%
  group_by(type) %>%
  nest() %>%
  mutate(M = map(data, function(dat){
    dat2 <- dat %>% spread(Species, n)
    M <- as.matrix(dat2[, -1])
    row.names(M) <- dat2$attribute
    return(M)
  }))%>%
  mutate(pvalue = map_dbl(M, ~chisq.test(.x)$p.value)) %>%
  select(-data, -M) %>%
  ungroup()


# in the example the results are the same but....the warning message is of concern and the function doesn't output the same in a more compelx dataset.

chi_test 
#> # A tibble: 2 x 2
#>   type  pvalue
#>   <chr>  <dbl>
#> 1 Petal      1
#> 2 Sepal      1
No_function 
#> # A tibble: 2 x 2
#>   type  pvalue
#>   <chr>  <dbl>
#> 1 Petal      1
#> 2 Sepal      1
# what am I doing wrong?

Создано в 2020-01-27 пакетом Представить (v0.3.0)

Что я здесь не так делаю?

Ответы [ 2 ]

1 голос
/ 27 января 2020

Нельзя использовать $ для косвенной ссылки на столбец (как в dat2$'z'), вместо этого используйте dat2[[z]]. Когда я заменяю это, нет никаких предупреждений / ошибок.

Попробуйте вместо этого эту версию вашей функции:

group_chi<-function(data, x, y, z){
  x <- enquo(x)
  y <- enquo(y)

  data %>%
    group_by(!! x) %>%
    nest() %>%
    mutate(M = map(data, function(dat){
      dat2 <- dat %>% spread(!! y, n)
      M <- as.matrix(dat2[, -1])
      row.names(M) <- dat2[[z]]
      return(M)
    }))%>%
    mutate(pvalue = map_dbl(M, ~chisq.test(.x)$p.value)) %>%
    select(-data, -M) %>%
    ungroup()
}

и затем вызовите со строкой:

chi_test <- group_chi(test,  type, Species, "attribute")

В качестве альтернативы вы можете сначала z <- enquo(z), затем pull(dat2, !!z) (как в ответе @ akrun).

group_chi<-function(data, x, y, z){
  x <- enquo(x)
  y <- enquo(y)
  z <- enquo(z)

  data %>%
    group_by(!! x) %>%
    nest() %>%
    mutate(M = map(data, function(dat){
      dat2 <- dat %>% spread(!! y, n)
      M <- as.matrix(dat2[, -1])
      row.names(M) <- pull(dat2, !!z)
      return(M)
    }))%>%
    mutate(pvalue = map_dbl(M, ~chisq.test(.x)$p.value)) %>%
    select(-data, -M) %>%
    ungroup()
}
group_chi(test,  type, Species, attribute)
# # A tibble: 2 x 2
#   type  pvalue
#   <chr>  <dbl>
# 1 Petal      1
# 2 Sepal      1
0 голосов
/ 27 января 2020

Мы также можем использовать z <- enquo(z), затем использовать select и pull для извлечения столбца как vector

group_chi<-function(data, x, y, z){
  x <- enquo(x)
  y <- enquo(y)
  z <- enquo(z)

  data %>%
    group_by(!! x) %>%
    nest() %>%
    mutate(M = map(data, function(dat){
      dat2 <- dat %>% spread(!! y, n)
      M <- as.matrix(dat2[, -1])

      row.names(M) <- dat2 %>% 
                           select(!!z) %>%
                           pull(1)
      return(M)
    }))%>%
    mutate(pvalue = map_dbl(M, ~chisq.test(.x)$p.value)) %>%
    select(-data, -M) %>%
    ungroup()
}

-проверка

chi_test <- group_chi(test,  type, Species, attribute)
chi_test
# A tibble: 2 x 2
#  type  pvalue
#  <chr>  <dbl>
#1 Petal      1
#2 Sepal      1

В более новых версиях tidyverse оператор curly-curly ({{}}) может заменить !!/enquo

group_chi<-function(data, x, y, z){

  data %>%
    group_by({{x}}) %>%
    nest() %>%
    mutate(M = map(data, function(dat){
      dat2 <- dat %>% spread({{y}}, n)
      M <- as.matrix(dat2[, -1])

      row.names(M) <- dat2 %>% 
                           pull({{z}})
      return(M)
    }))%>%
    mutate(pvalue = map_dbl(M, ~chisq.test(.x)$p.value)) %>%
    select(-data, -M) %>%
    ungroup()
}

chi_test <- group_chi(test,  type, Species, attribute)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...