我想在块对角线上应用两个函数,一个函数在数据框中的非对角线元素上应用第二个函数

I want to apply two functions one function on the block diagonal and the second function on the off-diagonal elements in the data frame

df<- data.frame(a=c(1:10), b=c(21:30),c=c(1:10), d=c(14:23),e=c(11:20),f=c(-6:-15),g=c(11:20),h=c(-14:-23),i=c(4:13),j=c(1:10))

在这个数据框中,我有三个块对角矩阵,如下图所示

我想应用两个函数,一个是块对角线的正弦函数,另一个是其他元素的余弦函数,生成相同结构的数据框。

sin(df[1:2,1:2])
sin(df[3:5,3:5])
sin(df[6:10,6:10])
cos(the rest of the elements)

1) outer/arithmetic 创建一个逻辑块对角矩阵,指示当前单元格是否在块对角线上,然后用它来进行凸组合sin 和 cos 值给出 data.frame 如下:

v <- rep(1:3, c(2, 3, 5))
ind <- outer(v, v, `==`)
ind * sin(df) + (!ind) * cos(df)

2) ifelse 或者,这会给出矩阵结果(或在上面使用 as.matrix)。 ind来自上面。

m <- as.matrix(df)
ifelse(ind, sin(m), cos(m))

3) Matrix::bdiag 另一种方法是使用 Matrix 包中的 bdiag(R 自带 -- 无需安装)。

library(Matrix)

ones <- function(n) matrix(1, n, n)
ind <- bdiag(ones(2), ones(3), ones(5)) == 1

现在按照 (1) 的最后一行或 (2) 的最后一行进行操作。

如果您不介意将结果存储在新的数据框中,您可以更改指令的顺序并按如下方式进行:

ndf <- cos(df)
ndf[1:2,1:2] <- sin(df[1:2,1:2])
ndf[3:5,3:5] <- sin(df[3:5,3:5])
ndf[6:10,6:10] <- sin(df[6:10,6:10])