合并两个不同大小的数据框并应用公式

时间:2015-09-17 15:02:20

标签: r

我有两个看起来像这样的数据框:

Name    Total
 A        43
 B        56
 C        98
 ...      ....

Name    col1    col2    col3    col4    ...
 A       2       3       4        0
 B       0       4       0        0    
 C       3       0       0        3
...     ...     ...     ...      ...

我想组合两个框架,在名称列上进行匹配,将col1,col2,col3等除以第一个数据框中的相应总数,并将其转换为百分比。所以输出应该如下所示:

Name    col1    col2    col3    col4    ...
 A      4.65    6.98    9.30      0
 B       0      7.14      0       0
 C      3.06      0       0     3.06
...

数据非常动态,我希望能够随着数据的发展再次运行此代码。第一个数据帧将保留格式,但第二个数据帧可能在数据的第二次迭代中有更多列。

我尝试过合并,但我似乎无法弄清楚如何应用分裂。

2 个答案:

答案 0 :(得分:0)

library(dplyr)
library(tidyr)

result = 
  total_data_frame %>%
  inner_join(column_data_frame) %>%
  gather(variable, value, -Name, -Total) %>%
  mutate(value = value/Total*100) %>%
  spread(variable, value)

说明:收集和传播是逆操作。它们有点难以解释,但是它们将收集的所有数据放入一列,然后反过来。它们有时是应用于列的可行选项,尤其是在数据集很小的情况下。

答案 1 :(得分:0)

我们可以使用base R执行此操作。一个选项是match第一个数据集('df1')中的'Name'列和第二个数据集('df2')中的df2[-1]来获取数字索引。根据该指数,我们从'df1'获得'Total'的元素。我们可以将除“名称”列(row(df2[-1]))之外的df2除以“总计”。使分子和分母具有相同的大小是有帮助的。为此,我们复制了“总计”。 round给出数据集的行索引,我们用它来复制'Total'的元素。在除法之后,我们可以乘以100和v1 <- df1$Total[match(df2$Name, df1$Name)] v2 <- v1[row(df2[-1])] df2[-1] <- round(100*df2[-1]/v2,2) df2 # Name col1 col2 col3 col4 #1 A 4.65 6.98 9.3 0.00 #2 B 0.00 7.14 0.0 0.00 #3 C 3.06 0.00 0.0 3.06 (如果需要)并将结果分配回“df2”列,不包括第一列。

df1 <- structure(list(Name = c("A", "B", "C"), Total = c(43L, 56L, 98L
)), .Names = c("Name", "Total"), class = "data.frame", row.names = c(NA, 
-3L))

df2 <- structure(list(Name = c("A", "B", "C"), col1 = c(2L, 0L, 3L), 
col2 = c(3L, 4L, 0L), col3 = c(4L, 0L, 0L), col4 = c(0L, 
0L, 3L)), .Names = c("Name", "col1", "col2", "col3", "col4"
), class = "data.frame", row.names = c(NA, -3L))

数据

{{1}}