Функция apply () by row требует, чтобы каждая строка была вектором цифр c - PullRequest
1 голос
/ 29 января 2020

У меня есть фрейм данных, такой как в этом примере:

       sample1 sample2 sample3
test1  0.1     0.3     0.03
test2  0.24    0.4     0.5
...(many rows)

Я пытаюсь apply() функция sumlog() из пакета metap, которая вычисляет объединенное значение p, используя Fisher's процедуры, для каждой строки кадра данных, каждая из которых состоит из 3 значений p, полученных в данном тесте, в 3 независимых выборках.

Эта функция работает следующим образом (для значений p в первой строке) :

sumlog(c(0.1, 0.3, 0.03))

, но поскольку

dt[1,]

приводит к

              sample1 sample2 sample3
test1            0.6408721                 0.2650909              0.8808415

и

class(dt[1,])

, это «data.frame», когда я запустите функцию apply ()

apply(dt, 1, sumlog)

, она возвращает

Ошибка в журнале (p [keep]): non-numberri c аргумент математической функции

- это то же самое, что и при запуске функции sumlog() для одной строки:

sumlog (dt [1,]) Ошибка в журнале (p [keep]) : non-Numberri c аргумент математической функции

Как я могу заставить apply() взять каждую строку в качестве вектора Numriri c для sumlog() для ее обработки?

РЕДАКТИРОВАТЬ :

> dput(head(df, 6))
structure(list(sample1 = list(0.640872129337761, 
0.609000106674239, 0.895097234385105, 0.965620545232963, 
0.383226609468318, 0.577994668964293), sample2 = list(
0.265090939404131, 0.472455371057292, 0.0126943959203454, 
0.0968610413223728, 0.881022723350396, 0.311841106080399), 
sample3 = list(0.880841481464769, 0.924264965127336, 
    0.684971652341359, 0.07916491063753, 0.204131282086192, 
    0.259781528310932)), row.names = c("test1", "test2", 
"test3", "test4", "test5", "test6"), class = "data.frame")

1 Ответ

4 голосов
/ 29 января 2020

Ваши данные имеют встроенные списки («списки-столбцы»).

str(dt)
# 'data.frame': 6 obs. of  3 variables:
#  $ sample1:List of 6
#   ..$ : num 0.641
#   ..$ : num 0.609
#   ..$ : num 0.895
#   ..$ : num 0.966
#   ..$ : num 0.383
#   ..$ : num 0.578
#  $ sample2:List of 6
#   ..$ : num 0.265
#   ..$ : num 0.472
#   ..$ : num 0.0127
#   ..$ : num 0.0969
#   ..$ : num 0.881
#   ..$ : num 0.312
#  $ sample3:List of 6
#   ..$ : num 0.881
#   ..$ : num 0.924
#   ..$ : num 0.685
#   ..$ : num 0.0792
#   ..$ : num 0.204
#   ..$ : num 0.26

В то время как «нормальные» кадры выглядят так:

str(mtcars[,1:3])
# 'data.frame': 32 obs. of  3 variables:
#  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
#  $ disp: num  160 160 108 258 360 ...

Чтобы сделать то, что вам нужно, сначала вы нужно unlist каждый столбец, затем вы можете делать свои вещи.

dt[] <- lapply(dt, unlist)
apply(dt, 1, sum)
#    test1    test2    test3    test4    test5    test6 
# 1.786805 2.005720 1.592763 1.141646 1.468381 1.149617 

(Использование dt[] <- вместо просто dt <-, потому что lapply вернет list вместо data.frame. Используя dt[], мы говорим «перезаписать столбцы этим списком объектов , но сохранить класс dt ».)

(я знаю, что я использую sum, а вы используете sumlog, но я считаю, что предпосылка все еще правильна, и ваши потребности будут работать со структурой, отличной от list.)

...