如何编写循环或函数以从数据框中获取具有重复值的矩阵?
How to write a loop or function to get a matrix with repetitions of values from a data frame?
我正在尝试从另一个数据框获取数据框,对某些值(在我的示例中为 a、b、c 和 d)重复执行一定次数(其值出现在我的第一个数据的每个单元格中框架)。为了更好地说明这一点,我展示了数据:
df<-data.frame(replicate(4,sample(20:50,10,rep=TRUE)))
a<-0
b<-1
c<-2
d<-9
我先试了:
for (i in 1:10)
{
print(rep(a, df[i,1]))
}
但是当我试图保存输出时,它只给我第一行分析:
for (i in 1:10)
{
output<-print(rep(a, df[i,1]))
}
然后我尝试了一些更复杂的东西,比如:
myfunc<-function(n){
a<-0
b<-1
c<-2
d<-9
IDs<- matrix(n[,1]) #A new column with the IDs for each row(rownames)
w = NULL
x = NULL
y = NULL
z = NULL
for (i in 1:nrow(n)) {
w<-rbind(t(as.matrix(rep(a, n[i,1]))))
x<-rbind(t(as.matrix(rep(b, n[i,2]))))
y<-rbind(t(as.matrix(rep(c, n[i,3]))))
z<-rbind(t(as.matrix(rep(d, n[i,4]))))
}
output<-cbind(IDs, w, x, y, z)
return(output <- as.data.frame(output))
}
但是我没有得到我需要的东西。
对于这样的矩阵:
预期输出为:
第一行:21 乘以 0、46 乘以 1、25 乘以 2 和 28 乘以 9。全部在 120 列中...以此类推其他行
如果您能帮我解决这个问题,我将不胜感激。
如果我理解正确,从 for
循环移动到 lapply
应该可以得到你想要的。
lapply(1:10, function(i) rep(a, df[i, 1]))
然后您可以通过
对所有列进行概括
l <- list(a = 0, b = 1, c = 2, d = 9)
lapply(seq_along(l), function(i) lapply(1:10, function(j) rep(l[[i]], df[j, i])))
它给你一个嵌套列表和(我认为)你想要的输出。
编辑
既然我更了解你想要什么,我想我可以提供更好的帮助。但在我看来,您在这里遇到了一个问题,因为您想要一个矩阵,但至少在您提供的示例中,矩阵的每一行的长度都不同。我没有用 NA
填充这些,而是创建了第五列来平衡事情。看看下面的内容是否能满足您的需求。
df$X5 <- (max(rowSums(df)) + 5) - rowSums(df)
l <- list(a = 0, b = 1, c = 2, d = 9, e = 5)
tmp <- lapply(seq_along(l), function(i) {
lapply(1:nrow(df), function(j) rep(l[[i]], df[j, i]))
})
max_col <- max(rowSums(df))
m <- matrix(rep(NA, length(l)*max_col), ncol = max_col)
for(i in seq_along(l)) {
m[i, ] <- unlist(lapply(tmp, "[[", i))
}
我认为你对矩阵第一行的期望是
r1 <- rep(c(0, 1, 2, 9), times=c(21, 46, 25, 28))
从第二行开始是
r2 <- rep(c(0, 1, 2, 9), times=c(47, 46, 45, 46))
?
如果是这样,那么如果您想将其放入数据框中,就会遇到长度不等的问题。
length(r1)
# [1] 120
length(r2)
# [1] 184
数据框无法处理,但列表可以
l <- list(r1, r2)
要对矩阵中的所有行执行此操作,您可以执行类似
的操作
mat <- matrix(c(21, 46, 25, 28,
47, 46, 45, 46,
35, 24, 46, 42,
27, 22, 36, 50), 4, byrow=TRUE)
l <- list()
for (row in 1:4) {
l[[row]] <- rep(c(0, 1, 2, 9), times=c(mat[row, 1], mat[row, 2],
mat[row, 3], mat[row, 4]))
}
sapply(l, length)
# [1] 120 184 147 135
我不知道 0 1 2 9
的来源,如果有所不同,您也必须将其考虑在内。如果实际矩阵中的列数量更多或不同,那么使用嵌套循环或 Daniel 建议的一些 lapply 魔法可能会更好。
如果你真的想要一个 matrix/data 帧类型结构,你可以通过填充 NA 来获得它,例如像这样
mat.new <- t(sapply(l, '[', seq(max(sapply(l, length)))))
我正在尝试从另一个数据框获取数据框,对某些值(在我的示例中为 a、b、c 和 d)重复执行一定次数(其值出现在我的第一个数据的每个单元格中框架)。为了更好地说明这一点,我展示了数据:
df<-data.frame(replicate(4,sample(20:50,10,rep=TRUE)))
a<-0
b<-1
c<-2
d<-9
我先试了:
for (i in 1:10)
{
print(rep(a, df[i,1]))
}
但是当我试图保存输出时,它只给我第一行分析:
for (i in 1:10)
{
output<-print(rep(a, df[i,1]))
}
然后我尝试了一些更复杂的东西,比如:
myfunc<-function(n){
a<-0
b<-1
c<-2
d<-9
IDs<- matrix(n[,1]) #A new column with the IDs for each row(rownames)
w = NULL
x = NULL
y = NULL
z = NULL
for (i in 1:nrow(n)) {
w<-rbind(t(as.matrix(rep(a, n[i,1]))))
x<-rbind(t(as.matrix(rep(b, n[i,2]))))
y<-rbind(t(as.matrix(rep(c, n[i,3]))))
z<-rbind(t(as.matrix(rep(d, n[i,4]))))
}
output<-cbind(IDs, w, x, y, z)
return(output <- as.data.frame(output))
}
但是我没有得到我需要的东西。
对于这样的矩阵:
预期输出为:
第一行:21 乘以 0、46 乘以 1、25 乘以 2 和 28 乘以 9。全部在 120 列中...以此类推其他行
如果您能帮我解决这个问题,我将不胜感激。
如果我理解正确,从 for
循环移动到 lapply
应该可以得到你想要的。
lapply(1:10, function(i) rep(a, df[i, 1]))
然后您可以通过
对所有列进行概括l <- list(a = 0, b = 1, c = 2, d = 9)
lapply(seq_along(l), function(i) lapply(1:10, function(j) rep(l[[i]], df[j, i])))
它给你一个嵌套列表和(我认为)你想要的输出。
编辑
既然我更了解你想要什么,我想我可以提供更好的帮助。但在我看来,您在这里遇到了一个问题,因为您想要一个矩阵,但至少在您提供的示例中,矩阵的每一行的长度都不同。我没有用 NA
填充这些,而是创建了第五列来平衡事情。看看下面的内容是否能满足您的需求。
df$X5 <- (max(rowSums(df)) + 5) - rowSums(df)
l <- list(a = 0, b = 1, c = 2, d = 9, e = 5)
tmp <- lapply(seq_along(l), function(i) {
lapply(1:nrow(df), function(j) rep(l[[i]], df[j, i]))
})
max_col <- max(rowSums(df))
m <- matrix(rep(NA, length(l)*max_col), ncol = max_col)
for(i in seq_along(l)) {
m[i, ] <- unlist(lapply(tmp, "[[", i))
}
我认为你对矩阵第一行的期望是
r1 <- rep(c(0, 1, 2, 9), times=c(21, 46, 25, 28))
从第二行开始是
r2 <- rep(c(0, 1, 2, 9), times=c(47, 46, 45, 46))
?
如果是这样,那么如果您想将其放入数据框中,就会遇到长度不等的问题。
length(r1)
# [1] 120
length(r2)
# [1] 184
数据框无法处理,但列表可以
l <- list(r1, r2)
要对矩阵中的所有行执行此操作,您可以执行类似
的操作mat <- matrix(c(21, 46, 25, 28,
47, 46, 45, 46,
35, 24, 46, 42,
27, 22, 36, 50), 4, byrow=TRUE)
l <- list()
for (row in 1:4) {
l[[row]] <- rep(c(0, 1, 2, 9), times=c(mat[row, 1], mat[row, 2],
mat[row, 3], mat[row, 4]))
}
sapply(l, length)
# [1] 120 184 147 135
我不知道 0 1 2 9
的来源,如果有所不同,您也必须将其考虑在内。如果实际矩阵中的列数量更多或不同,那么使用嵌套循环或 Daniel 建议的一些 lapply 魔法可能会更好。
如果你真的想要一个 matrix/data 帧类型结构,你可以通过填充 NA 来获得它,例如像这样
mat.new <- t(sapply(l, '[', seq(max(sapply(l, length)))))