Ошибка: оператор $ недопустим для атомов c - ggtern - PullRequest
2 голосов
/ 10 марта 2020

Отказ от ответственности: новичок в R.

Здравствуйте! Я пытаюсь построить тройные диаграммы образцов химии воды, используя пакет ggtern. Попытка запустить следующий код приводит к ошибке заголовка.

require(ggtern)

datos = read.csv("Li, B, Cl.csv", header = T, sep = ";", stringsAsFactors = FALSE)
names(datos) <- c("Muestra", "Li", "B", "Cl")

x11()
plot <- ggtern(data = datos, mapping = aes(x = as.numeric(datos[["Li"]]), y = as.numeric(datos[["Cl"]]), z = as.numeric(datos[["B"]]))) + geom_point()
plot

Насколько я понимаю, есть какая-то функция низкого уровня, ожидающая вектор атома c, но я даю ggtern как input, data.frame (проверено через str()).

После выполнения сценария dr aws ничего. Мои данные отформатированы следующим образом, но разделены точкой с запятой:

Muestra Li B Cl XYA3030 2.321334755 3.017842551 94.66082269 XEP3609 9.436334248 45.43581846 45.12784729 XEP3606_1 10.12604478 62.68726944 27.18668578 XEP3606_2 5.18367492 34.94305194 59.87327314 XEP3611 5.859786577 18.8098607 75.33035272 XEP3613 13.60173875 49.1191375 37.27912375 XEP3612 13.11960754 27.07316925 59.80722321 XEP3608 6.473636887 15.58523589 77.94112722 XEP3543 16.93515603 46.59573787 36.4691061

Это вывод "dput (datos)", как предлагается в комментариях.

> dput(datos)

structure(list(Muestra = c("XYA3030", "XEP3609", "XEP3606_1", 
"XEP3606_2", "XEP3611", "XEP3613", "XEP3612", "XEP3608", "XEP3543"
), Li = c(2.321334755, 9.436334248, 10.12604478, 5.18367492, 
5.859786577, 13.60173875, 13.11960754, 6.473636887, 16.93515603
), B = c(3.017842551, 45.43581846, 62.68726944, 34.94305194, 
18.8098607, 49.1191375, 27.07316925, 15.58523589, 46.59573787
), Cl = c(94.66082269, 45.12784729, 27.18668578, 59.87327314, 
75.33035272, 37.27912375, 59.80722321, 77.94112722, 36.4691061
)), class = "data.frame", row.names = c(NA, -9L))

Обновление: попробовал самый простой код, который я мог придумать, и все равно не повезло. Я что-то упустил из базы c?

library(ggtern)
datos = read.csv("Li_B_Cl.csv", header = T, sep = ";", stringsAsFactors = FALSE)
ggtern(data = datos, mapping = aes(x = Li, y = Cl, z = B)) + geom_point()

Обновление 2 : очистил сеанс RStudio и пакеты, переустановил ggtern и ggplot2, затем запустил простой код. Не повезло. Вот трассировка после ошибки:

> datos = read.csv("Li_B_Cl.csv", header = TRUE, sep = ";", stringsAsFactors = FALSE)
> ggtern(data = datos, mapping = aes(x = Li, y = Cl, z = B)) + geom_point()
Error: $ operator is invalid for atomic vectors
> traceback()
17: transform_position(data, panel_params$x$rescale, panel_params$y$rescale)
16: f(...)
15: self$super()$super()$transform(data, scale_details)
14: f(..., self = self)
13: self$transform(ex, scale_details)
12: .get.tern.extremes(self, list(x.range = self$limits$x, y.range = self$limits$y))
11: f(..., self = self)
10: self$coord$setup_panel_params(scale_x, scale_y, params = self$coord_params)
9: (function (scale_x, scale_y) 
   {
       self$coord$setup_panel_params(scale_x, scale_y, params = self$coord_params)
   })(dots[[1L]][[1L]], dots[[2L]][[1L]])
8: mapply(FUN = f, ..., SIMPLIFY = FALSE)
7: Map(setup_panel_params, scales_x, scales_y)
6: f(..., self = self)
5: layout$setup_panel_params()
4: ggplot_build.ggplot(x)
3: ggplot_build(x)
2: print.ggplot(x)
1: (function (x, ...) 
   UseMethod("print"))(x)

Ответы [ 2 ]

2 голосов
/ 10 марта 2020

Изменение на имена в aes исправляет это для меня:

library(ggtern)
ggtern(data = datos, mapping = aes(x = Li, y = Cl, z = B)) + geom_point()

ggtern

В общем, aes использует имена (или символы ), то есть без кавычек. Есть моменты, когда это нежелательно, например, когда вы не знаете имя заранее или хотите сделать это программно по другой причине. В тех случаях, когда у вас есть строки с именами переменных, можно также:

ggtern(data = datos, mapping = aes_string(x = "Li", y = "Cl", z = "B")) + geom_point()

(или var1 <- "Li", затем aes_string(x=var1, ...)).

Существуют другие rlang -путей делать что-то с использованием кавычек и тому подобного, что не обязательно относится к вашему вопросу.

Еще одна вещь, которую следует учитывать, это то, что вы обычно ссылаетесь на переменные, а не на векторы. В вашем коде у вас есть x = as.numeric(datos[["Li"]]), который пытается передать вектор значений. Кажется, это имеет смысл, хотя и не сработает. Одна из причин, по которой лучше всего разрешить ggplot2ggtern по наследству) управлять данными, состоит в том, чтобы сделать некоторые трюки, которые в противном случае потребовали бы немного больше внешнего / ручного отслеживания. Например, вы можете иметь слой, работающий только с подмножеством данных:

ggtern(data = datos, mapping = aes(x = Li, y = Cl, z = B)) + geom_point() +
  geom_point(color = "red", data = ~ subset(., grepl("XYA", Muestra)))
# the "." means "data as it exists so far" ^^^

(который окрашивает одну точку в «красный», не сталкиваясь с поднабором его самостоятельно). Это особенно полезно, когда данные, которые вы передаете в ggplot(data=...) или ggplot(data=...), предварительно отфильтрованы и / или находятся в конце канала, где в противном случае вам пришлось бы воссоздавать данные в слоях. Так что ... используйте имена / символы, не пытайтесь использовать векторы.

1 голос
/ 12 марта 2020

Переустановил версию пакетов, указанную @ r2evans (ggplot2-3.2.1, ggtern-3.1.0) вручную, используя install.packages(url, repos=NULL, type="source"), и вас ждет сюрприз! Это сработало. Я использую R 3.6.3, если это актуально.

...