подгонка нелинейной кривой к другой нелинейной кривой

Это не вопрос подгонки точек данных к кривой, но я хочу фактически подогнать образец кривой к моим стандартным кривым. Итак, у меня есть кадры данных только с длиной волны и Abs в качестве переменных, и у меня есть образец кадра данных (df) и три стандартные кривые (bc, chla, fuco) (см. ниже мой набор данных, извините, я должен поместить весь свой набор данных для вас, чтобы увидеть максимальное поглощение по сравнению с длиной волны.Для этого я бы включил только chla, и если бы вы могли помочь, я мог бы выяснить для двух других.)

    > dput(df)
    structure(list(Wavelength = 325:725, Abs = c(2.705, 2.654, 2.602, 
    2.556, 2.503, 2.462, 2.414, 2.369, 2.324, 2.284, 2.245, 2.218, 
    2.187, 2.149, 2.12, 2.09, 2.058, 2.031, 2.005, 1.973, 1.948, 
    1.925, 1.903, 1.885, 1.867, 1.844, 1.825, 1.809, 1.791, 1.776, 
    1.763, 1.75, 1.742, 1.716, 1.717, 1.708, 1.695, 1.688, 1.683, 
    1.677, 1.672, 1.667, 1.66, 1.657, 1.652, 1.649, 1.644, 1.64, 
    1.637, 1.634, 1.63, 1.626, 1.622, 1.619, 1.617, 1.615, 1.613, 
    1.612, 1.61, 1.609, 1.609, 1.608, 1.61, 1.611, 1.614, 1.617, 
    1.621, 1.625, 1.63, 1.635, 1.64, 1.646, 1.652, 1.658, 1.663, 
    1.668, 1.673, 1.679, 1.684, 1.689, 1.694, 1.702, 1.709, 1.718, 
    1.726, 1.734, 1.743, 1.75, 1.762, 1.772, 1.78, 1.788, 1.796, 
    1.803, 1.808, 1.814, 1.814, 1.817, 1.816, 1.816, 1.815, 1.812, 
    1.811, 1.807, 1.802, 1.797, 1.792, 1.787, 1.783, 1.778, 1.775, 
    1.771, 1.768, 1.764, 1.761, 1.755, 1.75, 1.743, 1.736, 1.728, 
    1.718, 1.705, 1.693, 1.678, 1.663, 1.647, 1.626, 1.608, 1.59, 
    1.57, 1.55, 1.532, 1.513, 1.495, 1.478, 1.462, 1.447, 1.431, 
    1.418, 1.403, 1.39, 1.378, 1.363, 1.349, 1.336, 1.323, 1.307, 
    1.292, 1.276, 1.258, 1.24, 1.223, 1.204, 1.185, 1.162, 1.144, 
    1.124, 1.102, 1.08, 1.062, 1.049, 1.027, 1.006, 0.988, 0.973, 
    0.955, 0.935, 0.919, 0.907, 0.891, 0.876, 0.861, 0.847, 0.835, 
    0.82, 0.808, 0.794, 0.782, 0.769, 0.758, 0.746, 0.733, 0.721, 
    0.708, 0.696, 0.686, 0.672, 0.66, 0.649, 0.638, 0.627, 0.615, 
    0.605, 0.595, 0.585, 0.576, 0.568, 0.558, 0.55, 0.542, 0.533, 
    0.527, 0.519, 0.512, 0.507, 0.501, 0.495, 0.489, 0.483, 0.478, 
    0.473, 0.467, 0.462, 0.458, 0.451, 0.447, 0.442, 0.438, 0.434, 
    0.429, 0.424, 0.419, 0.415, 0.41, 0.406, 0.402, 0.398, 0.393, 
    0.39, 0.385, 0.382, 0.377, 0.373, 0.367, 0.365, 0.36, 0.354, 
    0.352, 0.347, 0.344, 0.339, 0.337, 0.333, 0.329, 0.325, 0.32, 
    0.316, 0.312, 0.308, 0.306, 0.301, 0.297, 0.292, 0.289, 0.286, 
    0.282, 0.278, 0.274, 0.27, 0.267, 0.263, 0.259, 0.256, 0.253, 
    0.249, 0.245, 0.242, 0.239, 0.236, 0.233, 0.23, 0.228, 0.225, 
    0.224, 0.221, 0.219, 0.218, 0.217, 0.213, 0.212, 0.211, 0.21, 
    0.209, 0.208, 0.206, 0.204, 0.203, 0.202, 0.201, 0.199, 0.198, 
    0.197, 0.195, 0.195, 0.193, 0.192, 0.19, 0.19, 0.188, 0.19, 0.186, 
    0.185, 0.185, 0.184, 0.182, 0.183, 0.182, 0.182, 0.182, 0.182, 
    0.181, 0.18, 0.182, 0.182, 0.182, 0.184, 0.185, 0.186, 0.19, 
    0.193, 0.195, 0.2, 0.205, 0.21, 0.214, 0.221, 0.228, 0.235, 0.242, 
    0.249, 0.256, 0.264, 0.27, 0.278, 0.282, 0.289, 0.292, 0.297, 
    0.297, 0.298, 0.298, 0.293, 0.29, 0.288, 0.28, 0.273, 0.264, 
    0.253, 0.243, 0.232, 0.22, 0.209, 0.197, 0.187, 0.177, 0.167, 
    0.158, 0.149, 0.142, 0.136, 0.131, 0.126, 0.122, 0.117, 0.114, 
    0.109, 0.107, 0.104, 0.102, 0.1, 0.098, 0.095, 0.093, 0.092, 
    0.09, 0.088, 0.087, 0.086, 0.085, 0.082, 0.082, 0.08, 0.079, 
    0.077, 0.077, 0.076, 0.075, 0.075, 0.076, 0.073, 0.073, 0.072, 
    0.072, 0.071, 0.07, 0.069, 0.07, 0.068, 0.07, 0.068, 0.066)), .Names = c("Wavelength", 
    "Abs"), class = "data.frame", row.names = c(NA, -401L))



 > dput(chla)
    structure(list(Wavelength = 325:725, Abs = c(0.146, 0.149, 0.152, 
    0.156, 0.159, 0.162, 0.165, 0.168, 0.171, 0.174, 0.176, 0.178, 
    0.18, 0.182, 0.182, 0.182, 0.181, 0.179, 0.178, 0.175, 0.171, 
    0.169, 0.167, 0.165, 0.162, 0.161, 0.16, 0.16, 0.161, 0.162, 
    0.163, 0.166, 0.168, 0.17, 0.173, 0.176, 0.179, 0.182, 0.185, 
    0.189, 0.193, 0.196, 0.201, 0.204, 0.208, 0.213, 0.217, 0.22, 
    0.225, 0.229, 0.233, 0.238, 0.241, 0.244, 0.247, 0.25, 0.253, 
    0.255, 0.257, 0.258, 0.259, 0.26, 0.26, 0.26, 0.261, 0.261, 0.26, 
    0.26, 0.26, 0.261, 0.262, 0.263, 0.264, 0.265, 0.269, 0.27, 0.273, 
    0.277, 0.281, 0.286, 0.291, 0.296, 0.301, 0.306, 0.312, 0.318, 
    0.322, 0.326, 0.331, 0.334, 0.337, 0.339, 0.34, 0.342, 0.342, 
    0.343, 0.344, 0.345, 0.345, 0.347, 0.349, 0.35, 0.353, 0.356, 
    0.358, 0.359, 0.361, 0.362, 0.361, 0.36, 0.357, 0.351, 0.345, 
    0.336, 0.326, 0.313, 0.301, 0.284, 0.268, 0.25, 0.229, 0.21, 
    0.194, 0.172, 0.155, 0.137, 0.12, 0.105, 0.093, 0.08, 0.069, 
    0.059, 0.052, 0.045, 0.039, 0.034, 0.03, 0.026, 0.024, 0.021, 
    0.019, 0.018, 0.016, 0.015, 0.015, 0.013, 0.013, 0.012, 0.011, 
    0.011, 0.011, 0.011, 0.01, 0.011, 0.01, 0.01, 0.01, 0.008, 0.009, 
    0.009, 0.009, 0.01, 0.009, 0.009, 0.009, 0.01, 0.009, 0.009, 
    0.01, 0.009, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.009, 
    0.01, 0.01, 0.01, 0.01, 0.011, 0.011, 0.01, 0.011, 0.01, 0.011, 
    0.01, 0.011, 0.011, 0.012, 0.011, 0.011, 0.011, 0.012, 0.012, 
    0.013, 0.012, 0.013, 0.013, 0.013, 0.013, 0.014, 0.014, 0.014, 
    0.015, 0.015, 0.015, 0.016, 0.016, 0.016, 0.016, 0.016, 0.017, 
    0.016, 0.017, 0.016, 0.017, 0.016, 0.017, 0.018, 0.017, 0.018, 
    0.018, 0.02, 0.019, 0.019, 0.02, 0.019, 0.022, 0.021, 0.022, 
    0.022, 0.023, 0.024, 0.024, 0.026, 0.026, 0.027, 0.028, 0.029, 
    0.03, 0.031, 0.031, 0.033, 0.034, 0.034, 0.034, 0.035, 0.036, 
    0.037, 0.038, 0.039, 0.04, 0.04, 0.041, 0.041, 0.043, 0.044, 
    0.042, 0.045, 0.046, 0.044, 0.047, 0.048, 0.048, 0.049, 0.049, 
    0.051, 0.052, 0.054, 0.053, 0.056, 0.058, 0.06, 0.062, 0.063, 
    0.066, 0.068, 0.069, 0.073, 0.075, 0.077, 0.078, 0.082, 0.083, 
    0.083, 0.087, 0.088, 0.087, 0.09, 0.089, 0.089, 0.088, 0.087, 
    0.086, 0.085, 0.086, 0.086, 0.084, 0.084, 0.082, 0.083, 0.082, 
    0.082, 0.081, 0.081, 0.082, 0.082, 0.082, 0.081, 0.083, 0.084, 
    0.083, 0.086, 0.087, 0.088, 0.09, 0.093, 0.096, 0.101, 0.105, 
    0.114, 0.122, 0.132, 0.142, 0.155, 0.167, 0.183, 0.201, 0.219, 
    0.236, 0.261, 0.278, 0.296, 0.314, 0.331, 0.346, 0.356, 0.361, 
    0.364, 0.363, 0.358, 0.345, 0.333, 0.315, 0.293, 0.27, 0.245, 
    0.225, 0.202, 0.179, 0.158, 0.137, 0.116, 0.1, 0.085, 0.074, 
    0.061, 0.052, 0.044, 0.036, 0.032, 0.027, 0.023, 0.019, 0.017, 
    0.014, 0.01, 0.011, 0.007, 0.01, 0.008, 0.007, 0.006, 0.005, 
    0.003, 0.005, 0.005, 0.004, 0.004, 0.002, 0.004, 0.005, 0.004, 
    0.002, 0.001, 0.002, 0.003, 0.003, 0.002, 0.001, 0, 0.001, 0.002, 
    0.003, 0.004, 0.001, 0.001, 0.004)), .Names = c("Wavelength", 
    "Abs"), class = "data.frame", row.names = c(NA, -401L))

Итак, на самом деле я хотел сделать что-то вроде этого: подогнать мой стандарт к образцам

и извлечь данные для этого.

Может ли кто-нибудь указать мне правильное направление относительно того, какой пакет я могу использовать для этого? Любая помощь будет здорово. Спасибо


person Kaye11    schedule 06.02.2014    source источник
comment
Вы смотрели на пакет mixtools? В R-блогерах есть пост о его использовании. bit.ly/1b5rr4h   -  person matt_k    schedule 06.02.2014
comment
Но ваши данные не распределяются нормально. То, что вы связываете, представляет собой смешанный протокол распределения (см., например, пакет mixdist). Не думаю, что такой подход сработает. А как насчет суммирования строк (т. е. bc+chla+fluor)?   -  person Mikko    schedule 06.02.2014
comment
@Largh суммирование строк не сработает, так как один спектр не будет работать так хорошо, поскольку я также буду суммировать шумы от каждого из них. Спасибо за совет по mixtools и mixdist. Я посмотрю на это.   -  person Kaye11    schedule 06.02.2014
comment
@ Kaye11 Возможно, я недостаточно знаком с этой темой, но мне трудно понять, что вы хотите сделать. Включение другой переменной в пример может помочь. Вы можете merge наборы данных по столбцу длины волны и dput по ним.   -  person Mikko    schedule 06.02.2014


Ответы (1)


Попробуйте что-то вроде этого:

# not tested...
colnames(bc)[2]   <- "bc"
colnames(clha)[2] <- "clha"
colnames(fuco)[2] <- "fuco"

data <- merge(df,bc,by="Wavelength")
data <- merge(df,chla,by="Wavelength")
data <- merge(df,fuco,by="Wavelength")

fit <- lm(Abs~bc+chla+fuco, data=data)

Похоже, вы хотите найти, в каких пропорциях присутствуют стандарты в тесте. Итак, для любой длины волны

Abs = c1 × BC + c2 × CHLA + c3 × FUCO

и вы хотите определить c1, c2 и c3. Приведенный выше подход будет работать, если данные для всех 4 спектров имеют одинаковые длины волн (которые они имеют в вашем образце).

person jlhoward    schedule 06.02.2014
comment
Можем ли мы попытаться обратить проблему вспять? Я думаю, что я мог бы попытаться подогнать кривую выборки как комбинацию трех моих стандартов. Я хочу посмотреть, можно ли рассматривать спектры моих образцов как комбинацию 3-х пигментов, для которых у меня есть стандарты. ссылка Как видите, каждый пигмент имеет определенный узор на спектр длин волн, поэтому я хотел бы получить остатки, которые говорят мне, что комбинация x% стандарта1, y% стандарта2 и z% стандарта3 объясняет w% спектра образца. - person Kaye11; 07.02.2014
comment
Это именно то, что это делает. Если вы опубликуете два других стандарта, я смогу протестировать код, но вы действительно должны сначала попробовать его сами. Если не получится, отпишитесь, что пробовали и покажите результат. - person jlhoward; 07.02.2014