使用来自两个不同数据帧列表的数据应用函数

时间:2016-05-25 18:14:31

标签: r lapply mapply

我希望在另一个数据帧列表中进行的计算中使用相关数据帧列表中的数据。

目前,我的代码是这样的:

library(dplyr)

#Set up Dummy Data
types = c("A", "B", "C")
value = c(1, 2, 3, 4, 5, 6)
value3 = c(100, 150, 200, 250, 300, 350)
df_1 = data.frame(types, value, value3)

value2 = c(.1, .2, .3, .4, .5, .6)
value4 = c(.01, .02, .03, .04, .04, .06)
df_2 = data.frame(types, value2, value4)

#Split into lists
split1 = split(df_1, df_1$types)
split2 = split(df_2, df_2$types)

#run function inside of one list within each data frame.
split1 = lapply(split1, function(x) mutate(x, multiply = value * value3))
#run function inside of one list using data from corresponding data in different list
test = lapply(split2, function(x) select(x, value2))
lapply(split1, function(x) mutate(x, divide = value3/test)) 

最后一行代码生成错误“二元运算符的非数字参数”。

3 个答案:

答案 0 :(得分:0)

问题有点不清楚,但您似乎想要在公共列type上加入两组数据,并使用两组中的值进行操作。由于您似乎已经在使用dplyr包,让我们使用它来连接两个数据框,然后使用multiply创建新列(列名为dividemutate()):

library(dplyr)    
df_1 %>% left_join(df_2, by = 'types') %>% mutate(multiply = value * value3, 
                                                        divide = value3/value2)

输出:

   types value value3 value2 value4 multiply    divide
1      A     1    100    0.1   0.01      100 1000.0000
2      A     1    100    0.4   0.04      100  250.0000
3      B     2    150    0.2   0.02      300  750.0000
4      B     2    150    0.5   0.04      300  300.0000
5      C     3    200    0.3   0.03      600  666.6667
6      C     3    200    0.6   0.06      600  333.3333
7      A     4    250    0.1   0.01     1000 2500.0000
8      A     4    250    0.4   0.04     1000  625.0000
9      B     5    300    0.2   0.02     1500 1500.0000
10     B     5    300    0.5   0.04     1500  600.0000
11     C     6    350    0.3   0.03     2100 1166.6667
12     C     6    350    0.6   0.06     2100  583.3333

答案 1 :(得分:0)

由于您没有提供所需的输出,因此很难确切地说出您想要的内容,但是通过查看您的代码,您似乎需要在列表中的每个数据帧上使用另一个变量。为此,您只需稍微修改当前代码即可。只需将最后一行更改为:

res<-lapply(seq_along(split1), function(y, n, i) { 
                          mutate(y[[i]], divide = value3/as.data.frame(test[n[i]])) }, y=split1, n=names(split1)
             )

我们在这里做的是将索引传递给lapply函数,然后我们也将split1对象和names(split1)作为参数传递给函数。这样我们就可以按照我们想要的方式访问它们。结果是:

 res
[[1]]
  types value value3 multiply value2
1     A     1    100      100   1000
4     A     4    250     1000    625

[[2]]
  types value value3 multiply value2
2     B     2    150      300    750
5     B     5    300     1500    600

[[3]]
  types value value3 multiply   value2
3     C     3    200      600 666.6667
6     C     6    350     2100 583.3333

有两点需要注意:(1)名称不相同,我还没有弄清楚如何使用lapply来做到这一点,但事后可以很容易地做到:

names(res) <- names(split1)

和(2)看起来新变量名为value2但实际上divide就像我们在mutate中指定的那样。这可以通过以下方式看到:

 names(res[[1]])
[1] "types"    "value"    "value3"   "multiply" "divide"  

这看起来像显示问题,几乎就像变量标签与变量名称一样,我不知道如何立即修复它,但你仍然可以通过以下方式访问这些值:

 res[[1]]["divide"]
  value2
1   1000
4    625

答案 2 :(得分:0)

我相信你想要完成的是在两个不同的列表上应用一个函数,首先是两个列表的第一个元素,然后是两个元素的第二个元素等。

这是mapply()的作用。我已使用以下代码替换了您的最后一行代码:

result = split1

result$divide = mapply(function(x, y) {x$value3 / y$value2}, split1, test)

我想你明白了。您可以尝试使用dplyr执行相同的操作。