我必须使用R来关注问题 . 简而言之,我想基于数据框中不同列对的计算在数据帧中创建多个新列 .
数据如下:
df <- data.frame(a1 = c(1:5),
b1 = c(4:8),
c1 = c(10:14),
a2 = c(9:13),
b2 = c(3:7),
c2 = c(15:19))
df
a1 b1 c1 a2 b2 c2
1 4 10 9 3 15
2 5 11 10 4 16
3 6 12 11 5 17
4 7 13 12 6 18
5 8 14 13 7 19
输出应该如下所示:
a1 b1 c1 a2 b2 c2 sum_a sum_b sum_c
1 4 10 9 3 15 10 7 25
2 5 11 10 4 16 12 9 27
4 7 13 12 6 18 16 13 31
5 8 14 13 7 19 18 15 33
我可以使用dplyr以下列方式完成一些手动工作:
df %>% rowwise %>% mutate(sum_a = sum(a1, a2),
sum_b = sum(b1, b2),
sum_c = sum(c1, c2)) %>%
as.data.frame()
所以要做的是:在其中加上带有字母“a”的列,逐行计算总和,并创建一个名为sum_ [letter]的总和的新列 . 对具有不同字母的列重复此操作
这是有效的,但是,如果我有一个包含300个不同列对的大型数据集,那么手动输入将是重要的,因为我将不得不编写300个mutate调用 .
我最近偶然发现R包“purrr”,我的猜测是,这将解决我以更自动化的方式做我想做的事情的问题 .
特别是,我认为能够使用purrr:map2,我传递两个列名列表 .
-
list1 =其中包含数字1的所有列
-
list2 =其中包含数字2的所有列
然后我可以计算每个匹配列表条目的总和,形式为:
map2(list1, list2, ~mutate(sum))
但是,我无法弄清楚如何使用purrr最好地解决这个问题 . 我对使用purrr很新,所以我非常感谢你对这个问题的任何帮助 .
7 回答
1) dplyr/tidyr 转换为长格式,汇总并转换回宽格式:
赠送:
2) base using matrix multiplication
nms
是没有数字的列名的向量,以sum_
开头 .u
是它的独特元素的向量 . 使用outer
形成一个逻辑矩阵,当乘以DF
时得到总和 - 当完成时逻辑被转换为0-1 . 最后将它绑定到输入 .赠送:
3) base with tapply
使用
nms
(2)将tapply应用于每一行:赠送:
如果名称不是按升序排列,您可能希望在上面的表达式中用
factor(nms, levels = unique(nms))
替换nms .另一种解决方案是将
df
除以数字而不是使用Reduce
来计算sum
由reprex package(v0.2.0)创建于2018-04-13 .
如果您想考虑基本R方法,请按以下步骤操作:
它根据每个列名的第一个字母(a,b或c)将数据逐列拆分为列表 .
如果您有大量列并且需要区分除每个列名称末尾的数字之外的所有字符,则可以将方法修改为:
对于一个hackish整洁的解决方案,请检查出来:
基本上,我在所有行中收集所有列的值,将列名分成两部分,计算具有相同字母的列的行总和,然后将其转换回宽格式 .
这是
purrr
的一个选项 . 我们得到数据集names
的unique
前缀('nm1'),使用map
(来自purrr
)循环查找唯一名称select
matches
'nm1'前缀值的列,使用reduce
添加行并绑定列(bind_cols
)与原始数据集在基数R中,所有矢量化: