我有两个看起来像这样的数据框:
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
...
数据非常动态,我希望能够随着数据的发展再次运行此代码。第一个数据帧将保留格式,但第二个数据帧可能在数据的第二次迭代中有更多列。
我尝试过合并,但我似乎无法弄清楚如何应用分裂。
答案 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}}