#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)