我想根据另一个data.frame变量(或列表,如果出于某种原因最好与它们一起使用)的每个级别的条件,在data.frame变量的每个级别上运行一个函数。
如果其中一个变量达到某个条件(例如> 15),那么我想在每对变量上运行一个简单函数(例如product),然后将结果添加到新列表中。为了我的需求和他人的未来需求,我希望 对于任何条件和任何功能都灵活的解决方案。
我是Programming / R的新手,并且不知道如何为循环(或其他方法)构造适当的结构,以便为两个data.frame变量中的元素的所有组合运行函数。看起来这确实应该很容易实现,但是我已经花了好几个小时才找到解决方案。
这是我正在处理的嵌套的for循环代码:
df1 <- data.frame(c(1, 2, 3))
df2 <- data.frame(c(10, 20, 30))
list1 <- list()
for (i in 1:length(df1)) {
for (j in 1:length(df2)) {
if (df2[j,] > 15) {
list1[[i]] <- df1[i,] * df2[j,]}
}}
list1
运行当前代码时,我得到并清空列表结果:list()。 我想要返回的是这样的:
[[1]]
[1] 20
[[2]]
[1] 30
[[3]]
[1] 40
[[4]]
[1] 60
[[5]]
[1] 60
[[6]]
[1] 90
答案 0 :(得分:1)
考虑sapply
的两个输入,以使用列表转换遍历两个数据帧的nrow
:
mat <- sapply(1:nrow(df2), function(i, j) ifelse(df2[j,] > 15, df1[i,]*df2[j,], NA),
1:nrow(df1))
mat <- mat[!is.na(mat)]
mat
# [1] 20 30 40 60 60 90
as.list(mat)
# [[1]]
# [1] 20
#
# [[2]]
# [1] 30
#
# [[3]]
# [1] 40
#
# [[4]]
# [1] 60
#
# [[5]]
# [1] 60
#
# [[6]]
# [1] 90
答案 1 :(得分:1)
执行此操作的方法很多,这里有两种:一种是您的for
循环,另一种是矢量化的。
for
循环
您的代码中几乎没有错误,df1
和df2
都具有length
=1。因此,i
和j
仅设置为1可以通过使用nrow
而不是length
来解决。另一件事是在循环外创建一个index
,以将结果分配给列表。以下代码有效
df1 <- data.frame(c(1, 2, 3))
df2 <- data.frame(c(10, 20, 30))
list1 <- list()
index=0
for (i in 1:nrow(df1)) {
for (j in 1:nrow(df2)) {
if (df2[j,] > 15) {
index=index+1
list1[[index]] <- df1[i,] * df2[j,]}
}}
list1
[[1]]
[1] 20
[[2]]
[1] 30
[[3]]
[1] 40
[[4]]
[1] 60
[[5]]
[1] 60
[[6]]
[1] 90
矢量化方式
使用expand.grid
生成所需的组合,并使用prod
查找其产品
dat=expand.grid(df1[,1], df2[df2 > 15,1])
dat=dat[order(dat$Var1),]
apply(dat, 1, prod)
1 4 2 5 3 6
20 30 40 60 60 90