Сопоставление одного значения со всеми значениями в кадре данных в итерации на основе критериев

Это небольшой раздел моего фактического набора данных.

1           2           3           4           5      
57.033      57.0332     57.0333     57.0339     57.03332      
57.033      57.033      57.0335     59.0490     59.04901      
59.0489     59.048      59.0490589  60.0806     60.08   
60.0805     60          60.08       60          60.08059     
60.08053    60.080      60.08       61.0366     61.03947    

Вторая матрица той же структуры.

mz2

1       2           3           4           5
17.26   16.95225    17          17.84       17.79
14      141         143         632         629
630     63          631.337     241.5272    239
539     41          413         412         412
41      240         241         640         56

Мне нужно сравнить первое значение в столбце 1 со всеми значениями во всех столбцах, и если они соответствуют моим критериям, я должен добавить значение в первую строку этого конкретного столбца. Это произойдет в итерации. Затем я проверяю вторую строку в столбце 1 и сопоставляю все значения во всех столбцах, и если они соответствуют критериям, то добавляю их в строку 2 конкретного столбца.

Я пытался использовать циклы for, но это довольно запутанно.

Это моя попытка:

x.mz1<-matrix(0,5,5)        
b1.mz=mz[,1]       ##mz is my sample data above        
b2.mz=mz2[,1]    

for (i in length(b1.mz))    
{       
  one.mz=b1.mz[i]    
  one.2=b2.mz[i]    

  for (j in 2:ncol(mz))    
  {    
    two.1=mz[,j]    
    two=mz2[,j]    

   for (k in 1:length(two.1))
   {
  sec.mz=two.1[k]
  sec=two[k]
  cond1[k]<-one.mz-two.1<0.000005
  cond2[k]<-one.2-two<10
  cond.check<-cbind(cond1[k],cond2[k])
  cond.chc<-rbind(cond.check)
  browser()
}
  cond.chk.sum<-apply(cond.chc,1,sum)
  sum.check<-sum(cond.chk.sum==2,na.rm=T)

  if (sum.check==1)
  {
    x.mz1[i,j]=sec.mz
    }         

Что я пробовал в своем коде: я пытался сгенерировать логическую матрицу из всех итераций, и после того, как все строки в столбце 2 будут проверены на соответствие критериям, будет логическая матрица, и когда матрица будет сгенерирована, она будет иметь размер 5x2 для оба условия. Затем, когда оба условия ИСТИННЫ, я добавляю значение столбца 2 в строку 1, если я сравниваю первое значение в столбце 1.

Я надеюсь, что это ясно, поскольку я совершенно запутался после того, как попробовал все циклические структуры туда и обратно. Есть ли более простой способ сделать это, не используя так много циклов? с помощью lappy или какой-либо другой функции.

вывод: не точные значения, а чтобы дать представление о том, что я ожидаю в качестве вывода.

1               2           3               4               5      
57.03326875     57.03329    0           57.033      57    
57.03329688     0           0           0           59.049   
59.04894556     60.0805     59.049      60          0
60.0805355      0           0           60.080      60.080
60.08053673     61.039281   0           60.09           61.0839

первый столбец - это мой столбец 1 в основной матрице, и к нему рассчитываются все остальные столбцы. если я найду одно значение из всех совпадающих строк, я добавлю его в строку и соответствующий столбец, к которому принадлежит значение. 0 означает, что этому значению в столбце 1 не соответствует ни одно значение из всех строк в этом столбце.


person user2698508    schedule 25.12.2013    source источник
comment
Можете ли вы dput немного по обеим матрицам и ожидаемому результату? Также наметьте критерии больше. (разница в столбце ‹ 0,000005, разница во второй матрице ‹ 10 ?)   -  person Will    schedule 25.12.2013
comment
mz 1 и mz2 — меньшие участки всей матрицы. вся матрица огромная. Я не уверен, как лучше всего показать ожидаемый результат, но я добавлю его к вопросу, и если это не очень ясно, пожалуйста, дайте мне знать. Условие одно, например: строка 1 столбец 1 в mz1 равна 57,033. это значение следует сравнить со всеми строками в col2 до col5. Данные таковы, что для каждого столбца только одно значение будет соответствовать как условию 1, так и условию2. Таким образом, 57.033-57.0332 должно быть ‹0,000005.   -  person user2698508    schedule 25.12.2013
comment
Сделайте небольшой воспроизводимый пример. См. stackoverflow.com /вопросы/5963269/   -  person Roman Luštrik    schedule 25.12.2013
comment
Чтобы лучше понять, например, вам нужно найти строку и столбец, которые == 2 в, например, следующей матрице? ((mz2[1,1] - mz2[,-1]) < 10) + ((mz[1,1] - mz[,-1]) < 0.000005). Если это так, то есть более одного 2 с предоставленными вами примерами данных.   -  person alexis_laz    schedule 25.12.2013


Ответы (2)


Данные.

# data 
m1 <- structure(list(X1 = c(57.033, 57.033, 59.0489, 60.0805, 60.08053
), X2 = c(57.0332, 57.033, 59.048, 60, 60.08), X3 = c(57.0333, 
57.0335, 59.0490589, 60.08, 60.08), X4 = c(57.0339, 59.049, 60.0806, 
60, 61.0366), X5 = c(57.03332, 59.04901, 60.08, 60.08059, 61.03947
)), .Names = c("X1", "X2", "X3", "X4", "X5"), class = "data.frame", row.names = c(NA, 
-5L))

m2 <- structure(list(X1 = c(17.26, 14, 630, 539, 41), X2 = c(16.95225, 
141, 63, 41, 240), X3 = c(17, 143, 631.337, 413, 241), X4 = c(17.84, 
632, 241.5272, 412, 640), X5 = c(17.79, 629, 239, 412, 56)), .Names = c("X1", 
"X2", "X3", "X4", "X5"), class = "data.frame", row.names = c(NA, 
-5L))

Создание результатов условий в виде логических объектов.

# first columns
m1.c1 <- m1[,1]
m2.c1 <- m2[,1]

# first condition
res1 <- lapply(m1.c1,FUN=function(x){x-m1[,-1] < 0.00005})
# second condition
res2 <- lapply(m2.c1,FUN=function(x){x-m2[,-1] < 10})

# getting final condition as logical
res <- lapply(seq_along(m1.c1), FUN=function(x)(res1[[x]] & res2[[x]]))

Пока что, как сделать это с помощью lapply.

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

person Petr Matousu    schedule 25.12.2013

Обновление: с первой попытки я проверил только следующий столбец. Я сделал небольшую ревизию исходных данных и отредактировал цикл. См. значение 1.2.

Я не уверен, что полностью понимаю вашу просьбу, но вот попытка.

# generate data
  v1 <- c(1.2, 5, 9, 13, 17)
  v2 <- c(1, 1.3, 10, 14, 18)
  v3 <- c(2, 6, 1.4, 15, 1.2)
  v4 <- c(3, 7, 11, 1.5, 1.4)
  v5 <- c(4, 8, 12, 16, 1.5)
  dat <- as.data.frame(cbind(v1, v2, v3, v4, v5))

  dat
      v1   v2   v3   v4   v5
  1  1.2  1.0  2.0  3.0  4.0
  2  5.0  1.3  6.0  7.0  8.0
  3  9.0 10.0  1.4 11.0 12.0
  4 13.0 14.0 15.0  1.5 16.0
  5 17.0 18.0  1.2  1.4  1.5

dat2 <- dat
for (r in 1:nrow(dat)) {                    # loop through rows
  for (v in 1:length(dat)) {                # loop through columns
    v.check <- v + 1
      while (v.check < length(dat)) {
        if (dat[r,v] %in% dat[,v.check]==TRUE) {
          dat2[r,v.check] <- dat[r,v]
          v.check <- v
          break
        } else {
          v.check <- v.check + 1
      }
    }
  }
}   

dat2
    v1   v2   v3  v4   v5
1  1.2  1.0  1.2 3.0  4.0
2  5.0  1.3  6.0 7.0  8.0
3  9.0 10.0  1.4 1.4 12.0
4 13.0 14.0 15.0 1.5 16.0
5 17.0 18.0  1.2 1.4  1.5
person Eric Green    schedule 25.12.2013