Как применить функцию к каждой строке фрейма данных? - PullRequest
0 голосов
/ 26 октября 2019

Я хотел бы использовать этот метап из пакета для вычисления нескольких значений o

У меня есть мой фрейм данных со значениями 3 p

    > dput(head(tt))
structure(list(RS = c("rs2089177", "rs4360974", "rs6502526", 
"rs8069906", "rs9905280", "rs4313843"), G = c(0.9986, 0.9738, 
0.9744, 0.7184, 0.7205, 0.9804), E = c(0.7153, 0.7838, 0.7839, 
0.4918, 0.4861, 0.8522), B = c(0.604716, 0.430228, 0.42916, 0.521452, 
0.465758, 0.474313)), class = c("data.table", "data.frame"), row.names  = c(NA, 
-6L), .internal.selfref = <pointer: 0x10200eee0>)

и фрейм данных с соответствующими весами для каждого изЗначения p из фрейма данных tt

   > dput(head(df))
structure(list(wg = c(40.6324993078201, 40.6324993078201, 40.6324993078201, 
 40.6324993078201, 40.6324993078201, 40.6324993078201), we = c(35.3977400408557, 
35.3977400408557, 35.3977400408557, 35.3977400408557, 35.3977400408557, 
35.3977400408557), wb = c(580.643608420863, 580.643608420863, 
580.643608420863, 580.643608420863, 580.643608420863, 580.643608420863
), RS = c("rs2089177", "rs4360974", "rs6502526", "rs8069906", 
"rs9905280", "rs4313843")), row.names = c(NA, 6L), class = "data.frame")

Столбец RS одинаков в df и tt

Как использовать эту функцию sunz () для создания нового фрейма данных, который будет выглядеть одинаковокак только у tt будет дополнительный столбец, скажем, с именем «META», который рассчитал значения meta p для каждой строки

Это пример того, сколько будет p-значение в первой строке:

 > sumz(c(0.9986,0.7153,0.604716), weights = c(40.6325,35.39774,580.6436), na.action = na.fail)
p =  0.6940048

это функция, о которой я говорил: https://www.rdocumentation.org/packages/metap/versions/1.1/topics/sumz

Я попытался объединить эти два фрейма данных и применить функцию к каждой строке:

> head(q)
       ID         P         G       E       wb      wg       we
1:  rs1029830 0.0979931 0.0054060 0.39160 580.6436 40.6325 35.39774
2:  rs1029832 0.1501820 0.0028140 0.39320 580.6436 40.6325 35.39774
3: rs11078374 0.1701250 0.0009805 0.49730 580.6436 40.6325 35.39774
4:  rs1124961 0.1710150 0.7252000 0.05737 580.6436 40.6325 35.39774
5:  rs1135237 0.1493650 0.6851000 0.06354 580.6436 40.6325 35.39774
6: rs11867934 0.0757972 0.0006140 0.00327 580.6436 40.6325 35.39774


helper <- function(x) {
   p <- sumz(x[2:4], weights = x[5:7])$p
   p
}

q$META <- apply(q, MARGIN = 1, helper)

, но я получаю этоошибка:

 Error in sumz(x[2:4], weights = x[5:7]) : 
  Must have at least two valid p values 

1 Ответ

0 голосов
/ 26 октября 2019

Для начала, так как вы говорите, что RS одинаково между двумя, для меня звучит предостережение «Насколько мы уверены, что строки всегда выстраиваются правильно?» Для защитыЯ скажу «не на 100%», и объединю / объединю их вместе, чтобы они гарантировались в правильном порядке.

quux <- tt[df, on="RS"]
quux
#           RS      G      E        B      wg       we       wb
# 1: rs2089177 0.9986 0.7153 0.604716 40.6325 35.39774 580.6436
# 2: rs4360974 0.9738 0.7838 0.430228 40.6325 35.39774 580.6436
# 3: rs6502526 0.9744 0.7839 0.429160 40.6325 35.39774 580.6436
# 4: rs8069906 0.7184 0.4918 0.521452 40.6325 35.39774 580.6436
# 5: rs9905280 0.7205 0.4861 0.465758 40.6325 35.39774 580.6436
# 6: rs4313843 0.9804 0.8522 0.474313 40.6325 35.39774 580.6436

Отсюда, это просто применение каждой части строки с другойчасть той же строки, для каждой строки:

quux$META <- sapply(seq_len(nrow(quux)), function(rn) {
  unlist(sumz(as.matrix(quux[,.(G,E,B)])[rn,], weights = as.vector(quux[,.(wg,we,wb)])[rn,],
              na.action=na.fail)["p"])
})
quux
#           RS      G      E        B      wg       we       wb      META
# 1: rs2089177 0.9986 0.7153 0.604716 40.6325 35.39774 580.6436 0.9863582
# 2: rs4360974 0.9738 0.7838 0.430228 40.6325 35.39774 580.6436 0.9294546
# 3: rs6502526 0.9744 0.7839 0.429160 40.6325 35.39774 580.6436 0.9300445
# 4: rs8069906 0.7184 0.4918 0.521452 40.6325 35.39774 580.6436 0.6379392
# 5: rs9905280 0.7205 0.4861 0.465758 40.6325 35.39774 580.6436 0.6055061
# 6: rs4313843 0.9804 0.8522 0.474313 40.6325 35.39774 580.6436 0.9605584

или более data.table -центрический путь:

mysumz <- function(x, w) sumz(unlist(x), weights = unlist(w), na.action = na.fail)[["p"]]
quux[, META := mysumz(.(G,E,B), .(wg,we,wb)), by = seq_len(nrow(quux))]

(заимствование из https://stackoverflow.com/a/36802640). Вторичная функциятребуется, потому что каждый вызов mysumz имеет list для каждого из x и w, но sumz нужны векторы. Если вы хотите проверить это, сначала позвоните debugonce(mysumz), а затем выполните quux[,META:=...]и посмотрите x и w ... и как это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...