将函数应用于R中每n列的每一行
Applying a function to every row on each n number of columns in R
我的数据包含连续的列 1,2,...,2000。我想为每行 100 列的每组应用 returns 3 个变量的函数。
数据如下所示:
1 2 3 ..... 2000
0.01 0.0 0.002 0.03
0.005 0.002 0.011 0.04
0.001 0.003 0.004 0.0
这是我试过的代码:
prep_data <- function(df){
#Create Column names
colnms<-c()
for(i in seq(1, 20, 1)){
for(j in seq(1, 3, 1)){
f<-paste0("grp",i,"_",j)
colnms=c(colnms,f)
}
}
#
trans <- data.frame(matrix(ncol = 60, nrow = NROW(df)))
colnames(trans) <-colnms
#Looping over every row
for (i in 1:NROW(df)){
X = c()
#LOOPING over each group of 100 columns
for(j in seq(1, 1900, 100)){
end<-j+99
tmp<-subset(df[i], select=j:end)
#Here I apply the function over the 100 columns for the current row to get 3 values#
X = c(X,MY_FUNC(tmp))
###################################################################################
}
}
#Append the current row
trans[i,] <- X
}
return(trans)
}
预期输出(60 列的数据框)如下:
grp1_1 grp1_2 grp1_3 ..... grp20_3
0.01 0.0 0.002 0.03
0.005 0.002 0.011 0.04
0.001 0.003 0.004 0.0
我的代码运行但速度太慢可能是因为它对所有循环都没有效率
提前致谢
这是一种方法:
让 d
成为您的 3 行 x 2000 列框架,列名 as.character(1:2000)
(请参阅下面的假数据生成)。我们使用 .I
添加行标识符,然后将数据融长,添加 grp
和 column-group 标识符(即标识 20 组 100)。然后按行和组应用你的函数 myfunc
(请参阅下文中的 stand-in 函数),并按行和组进行调整。 (我用的是stringr::str_pad
在组号前面加0)
# add row identifier
d[, row:=.I]
# melt and add col group identifier
dm = melt(d,id.vars = "row",variable.factor = F)[,variable:=as.numeric(variable)][order(variable,row), grp:=rep(1:20, each=300)]
# get the result (180 rows long), applying myfync to each set of columns, by row
result = dm[, myfunc(value), by=.(row,grp)][,frow:=rep(1:3,times=60)]
# swing wide (3 rows long, 60 columns wide)
dcast(
result[,v:=paste0("grp",stringr::str_pad(grp,2,pad = "0"),"_",row)],
frow~v,value.var="V1"
)[, frow:=NULL][]
输出:(仅前六列)
grp01_1 grp01_2 grp01_3 grp02_1 grp02_2 grp02_3
<num> <num> <num> <num> <num> <num>
1: 0.54187168 0.47650694 0.48045694 0.51278399 0.51777319 0.46607845
2: 0.06671367 0.08763655 0.08076939 0.07930063 0.09830116 0.07807937
3: 0.25828989 0.29603471 0.28419957 0.28160367 0.31353016 0.27942687
输入:
d = data.table()
alloc.col(d,2000)
set.seed(123)
for(c in 1:2000) set(d,j=as.character(c), value=runif(3))
myfunc
函数(此答案的玩具示例):
myfunc <- function(x) c(mean(x), var(x), sd(x))
我的数据包含连续的列 1,2,...,2000。我想为每行 100 列的每组应用 returns 3 个变量的函数。
数据如下所示:
1 2 3 ..... 2000
0.01 0.0 0.002 0.03
0.005 0.002 0.011 0.04
0.001 0.003 0.004 0.0
这是我试过的代码:
prep_data <- function(df){
#Create Column names
colnms<-c()
for(i in seq(1, 20, 1)){
for(j in seq(1, 3, 1)){
f<-paste0("grp",i,"_",j)
colnms=c(colnms,f)
}
}
#
trans <- data.frame(matrix(ncol = 60, nrow = NROW(df)))
colnames(trans) <-colnms
#Looping over every row
for (i in 1:NROW(df)){
X = c()
#LOOPING over each group of 100 columns
for(j in seq(1, 1900, 100)){
end<-j+99
tmp<-subset(df[i], select=j:end)
#Here I apply the function over the 100 columns for the current row to get 3 values#
X = c(X,MY_FUNC(tmp))
###################################################################################
}
}
#Append the current row
trans[i,] <- X
}
return(trans)
}
预期输出(60 列的数据框)如下:
grp1_1 grp1_2 grp1_3 ..... grp20_3
0.01 0.0 0.002 0.03
0.005 0.002 0.011 0.04
0.001 0.003 0.004 0.0
我的代码运行但速度太慢可能是因为它对所有循环都没有效率
提前致谢
这是一种方法:
让 d
成为您的 3 行 x 2000 列框架,列名 as.character(1:2000)
(请参阅下面的假数据生成)。我们使用 .I
添加行标识符,然后将数据融长,添加 grp
和 column-group 标识符(即标识 20 组 100)。然后按行和组应用你的函数 myfunc
(请参阅下文中的 stand-in 函数),并按行和组进行调整。 (我用的是stringr::str_pad
在组号前面加0)
# add row identifier
d[, row:=.I]
# melt and add col group identifier
dm = melt(d,id.vars = "row",variable.factor = F)[,variable:=as.numeric(variable)][order(variable,row), grp:=rep(1:20, each=300)]
# get the result (180 rows long), applying myfync to each set of columns, by row
result = dm[, myfunc(value), by=.(row,grp)][,frow:=rep(1:3,times=60)]
# swing wide (3 rows long, 60 columns wide)
dcast(
result[,v:=paste0("grp",stringr::str_pad(grp,2,pad = "0"),"_",row)],
frow~v,value.var="V1"
)[, frow:=NULL][]
输出:(仅前六列)
grp01_1 grp01_2 grp01_3 grp02_1 grp02_2 grp02_3
<num> <num> <num> <num> <num> <num>
1: 0.54187168 0.47650694 0.48045694 0.51278399 0.51777319 0.46607845
2: 0.06671367 0.08763655 0.08076939 0.07930063 0.09830116 0.07807937
3: 0.25828989 0.29603471 0.28419957 0.28160367 0.31353016 0.27942687
输入:
d = data.table()
alloc.col(d,2000)
set.seed(123)
for(c in 1:2000) set(d,j=as.character(c), value=runif(3))
myfunc
函数(此答案的玩具示例):
myfunc <- function(x) c(mean(x), var(x), sd(x))