ggplot с переменными x и y в разных данных.кадры с циклом For

#r #dataframe #for-loop #ggplot2 #physics

Вопрос:

У меня есть два фрейма данных для моего значения x и y. Это было сделано потому, что каждая строка представляет несколько выборок от одного и того же человека, и каждый человек также имеет уникальные значения x. Пример моей таблицы значений y:

Группа подгруппа ранг диаметр ID peak 1 peak 2 peak 3 peak 4 peak 5
Хим Полисты 6 4.3 ОБЪЯВЛЕНИЕ 39 241.878 390.415 518.534 625.108 742.561
Макать Каллип 4 3.2 AD42 45.937 102.299 151.484 182.305 NA

(но с ~200 строками и дополнительными столбцами «пик», которые доходят до «пика 16»)

и образец моей таблицы значений x:

ID дисп1 дисп2 дисп3 дисп4 дисп5
ОБЪЯВЛЕНИЕ 39 0.0591 0.118 0.177 0.236 0.295
AD42 0.102 0.203 0.305 0.406 0.508

(опять же, столбцы «disp» увеличиваются до «disp16)

Итак, здесь у меня есть 2 образца, в основном подвергающихся кривым напряжения-деформации. «пик»-это сила (g) от заданной величины смещения, мое значение x, представленное как доля от общего сжимаемого диаметра (т. е. смещение/общий диаметр. Каждый шаг перемещения составляет 0,254 мм, поэтому disp1 =0,254/общий диаметр, disp2=0,508/общий диаметр и т.д.).

Для моей точечной диаграммы значения y-это столбцы «пик», а мои значения x-это мои значения «disp». Это означает,что координаты первой точки AD39 будут (0,0591, 241,878), второй — (0,118,390,415) и т. Д. Как вы можете видеть из объявления 42, не все значения x имеют соответствующие значения y.

Я сопоставил данные с помощью цикла For

 dy<-read_excel(file name for y-value table)
dx<-read_excel(file name for y-value table)
n<- nrow(dx)

disp<- data.frame(NA, dim = c(n,16))
peak<- data.frame(NA, dim = c(n,16))
for (i in 1:n) {
  for (j in 1:16) {
    disp[i,j]<- dx[i,j 1]
    peak[i,j]<- dy[i,j 6] 
  }
}
names(disp)<- c(1:16)
names(peak)<- c(1:16)
 

then I plotted the data like this:

 plot(as.numeric(disp[1,1:16]), as.numeric(peak[1,1:16]), pch = 20, xlab = "displacement", ylab = "peak")
#plot all points
for (i in 2:n) {
  points(as.numeric(disp[i,1:16]), as.numeric(peak[i,1:16]), pch = 20)
}
 

(Я признаю, что знакомый сделал для меня цикл for после того, как я потратил много часов, пытаясь заставить cbind работать; я не очень хорошо понимаю циклы for)

По сути, моя конечная цель состоит в том, чтобы легко разделить данные на различные группы факторов; напр. Я хочу сравнить мои 37 образцов с рангом «6» с моими 82 образцами с рангом «4», построив их на одном и том же наборе осей, или мои 45 образцов «Хим» с моими 93 образцами «Дип».

Я думаю, что мог бы перебить код грубой силой с помощью группы функций подмножества (), но существует так много групп факторов, что это заняло бы несколько часов и было бы самым неуклюжим кодом в мире.

Я хочу сделать это в ggplot, потому что это лучший графический пакет, и он также позволяет вам подмножать данные в функции ggplot.

К сожалению, я не могу изобразить ни одного образца на ggplot, благодаря моему циклу For. Это была моя попытка:

 library(ggplot2)
ggplot(data=data.frame(x=(as.numeric(disp[1:16])),y=(as.numeric(peak[1:16]))),aes(x=(as.numeric(disp[1,1:16])), y=(as.numeric(peak[1,1:16])))) geom_point(size=2,shape=23)
 

ошибка, которую я получаю за это, — «Ошибка в data.frame(x = (как.числовой(disp[1:16])), y = (как.числовой(пик[1:16]))) :
объект «список» нельзя принудить ввести «двойной»»

Я предполагаю, что эта ошибка^ связана с функцией «as.numeric» в моем data.frame. Поэтому я удалил его, только чтобы получить: «Ошибка: Эстетика должна быть либо длиной 1, либо такой же, как данные (167): x и y».

Я предполагаю, что проблема в значениях NA в моих значениях y, в которых есть «NA». Честно говоря, не знаю, как с этим справиться.

Итак, после многих поворотов и поворотов я здесь. Я не уверен, является ли решение прямым или его можно решить, только изменив то, как я работаю со своими данными.

Комментарии:

1. Я бы рекомендовал преобразовать ваши данные в более длинный формат, где каждый образец получает строку, затем соединить две таблицы, а затем добавить итоговое значение для каждого человека с его рангом. Подача этого в ggplot будет очень простой, например. reshaped_data %>% ggplot(aes(disp, peak, group = ID)) geom_point() facet_wrap(~rank)

Ответ №1:

Вот мое предложение:

Во-первых, измените формат двух таблиц на длинный:

 library(tidyverse)
y_value_long <- y_value_table %>%
  pivot_longer(-c(Group:ID), names_prefix = "peak.", 
               names_transform = list(name = as.integer), 
               values_to = "peak")

x_value_long <-  x_value_table %>% 
      pivot_longer(-ID, names_prefix = "disp", 
                   names_transform = list(name = as.integer), 
                   values_to = "disp")
 

Присоединяйтесь к ним и составляйте заговор, разделяясь по рангам.

 left_join(y_value_long, x_value_long, by = c("ID", "name")) %>%
  ggplot(aes(disp, peak, group = ID))  
  geom_point()  
  geom_path()    # using _path here instead of _line b/c you might have multiple force values yielding the same displacement
  facet_wrap(~rank)
 

введите описание изображения здесь

Комментарии:

1. Иметь ваши данные в длинном формате всегда хорошая идея (в мире ggplot)