Я использую R, и у меня есть два data.frames, A
и B
. Оба имеют 6 строк, но A
имеет 25000 столбцов (генов), а B
имеет 30 столбцов. Я хотел бы применить функцию с двумя аргументами f (x, y)
, где x
- это каждый столбец A
и y
каждый столбец B
. Пока это выглядит так:
i = 1
for (x in A){
j = 1
for (y in B){
out[i,j] <- f(x,y)
j = j + 1
}
i = i + 1
}
У меня есть две проблемы с этим: из моего программирования на Python я ассоциирую отслеживание таких счетчиков как грубые, а из моего программирования на R я нервничаю из-за циклов. Тем не менее, я могу Я не понимаю, как применить применить
(или даже если я должен применить применить
) к этой проблеме и надеялся, что кто-то может просветить меня. Мне нужно обработать f ()
как атомарный (сейчас это на самом деле cor.test ()
).
Поскольку вы используете фреймы данных, может быть быстрее использовать lapply или sapply для этого (особенно с учетом объема ваших фреймов данных). Например,
x <- data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), col3=c(9,10,11,12))
y <- data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8))
bl <- lapply(x, function(u){
lapply(y, function(v){
f(u,v) # Function with column from x and column from y as inputs
})
})
out = matrix(unlist(bl), ncol=ncol(y), byrow=T)
Некоторые данные
nrows <- 6
A <- data.frame(a = runif(nrows), b = runif(nrows), c = runif(nrows))
B <- data.frame(z = rnorm(nrows), y = rnorm(nrows))
Хитрость: запомните столбцы с expand.grid
counter <- expand.grid(seq_along(A), seq_along(B))
f <- function(x)
{
cor.test(A[, x["Var1"]], B[, x["Var2"]])$estimate
}
Теперь нам нужен только 1 вызов для apply
.
stats <- apply(counter, 1, f)
names(stats) <- paste(names(A)[counter$Var1], names(B)[counter$Var2], sep = ",")
stats
Вложенность apply работает, хотя синтаксис не самый простой.
x<-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), col3=c(9,10,11,12))
y<-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8))
z<-apply(x,2,function(col,df2)
{
apply(df2,2,function(col2,col1)
{
col2+col1
},col)
},y)
z
col1 col2 col3
[1,] 2 6 10
[2,] 4 8 12
[3,] 6 10 14
[4,] 8 12 16
[5,] 6 10 14
[6,] 8 12 16
[7,] 10 14 18
[8,] 12 16 20