r - 通过循环匹配列名中的字符串模式并作为新列附加到数据框
问题描述
我有一个列名如下的数据框:
abc_alpha = c(1,2,3,4)
abc_beta = c(5,6,7,8)
abc_char = c(9,10,11,12)
xyz_alpha = c(4,3,2,1)
xyz_beta = c(8,7,6,5)
xyz_char = c(12,11,10,9)
和我的数据框(df):
abc_alpha abc_beta abc_char xyz_alpha xyz_beta xyz_char
1 5 9 4 8 12
2 6 10 3 7 11
3 7 11 2 6 10
4 8 12 1 5 9
我想遍历列并匹配具有相同字符串结尾的列(在下划线之后),取两个匹配列的平均值并将其作为新变量附加到数据框的末尾(列名对于新变量将是下划线后的匹配字符串)。我想使用循环而不是对列名进行硬编码,因为真实数据集的列太多。
预期输出将是:
abc_alpha abc_beta abc_char xyz_alpha xyz_beta xyz_char alpha beta char
1 5 9 4 8 12 2.5 6.5 10.5
2 6 10 3 7 11 2.5 6.5 10.5
3 7 11 2 6 10 2.5 6.5 10.5
4 8 12 1 5 9 2.5 6.5 10.5
我已经编写了循环函数的第一部分,但似乎无法通过将新列附加到数据框来完成:
for (i in 1:ncol(df)) {
x <- (strsplit(names(df)[i], split = '_', fixed = T))[[1]][2]
我浏览了可能类似的问题,但由于我是 R 新手,很多建议使用 Apply 系列的答案让我感到困惑,我无法根据我的情况调整这些解决方案。
谢谢!
解决方案
我们可以split
通过删除子字符串创建的分组变量来获取数据并获得rowMeans
cbind(df, sapply(split.default(df, sub(".*_", "", names(df))), rowMeans))
#abc_alpha abc_beta abc_char xyz_alpha xyz_beta xyz_char alpha beta char
#1 1 5 9 4 8 12 2.5 6.5 10.5
#2 2 6 10 3 7 11 2.5 6.5 10.5
#3 3 7 11 2 6 10 2.5 6.5 10.5
#4 4 8 12 1 5 9 2.5 6.5 10.5
或者使用tidyverse
,gather
将列转换为'long'格式,然后separate
将'key'列通过分隔符分成两列_
,summarise
以获取mean
按行名和'key2'分组后,spread
到'wide'并使用与原始数据集绑定`bind_cols'
library(tidyverse)
df %>%
rownames_to_column('rn') %>% # create a rowname column
gather(key, val, -rn) %>% # convert to long format
separate(key, into = c('key1', 'key2')) %>% # split column into two
group_by(rn, key2) %>% # grouping with columns
summarise(val = mean(val)) %>% # get the mean
spread(key2, val) %>% # convert to wide format
ungroup %>% # remove the groups
select(-rn) %>% # select only columns of interest
bind_cols(df, .) # bind with the original dataset
# abc_alpha abc_beta abc_char xyz_alpha xyz_beta xyz_char alpha beta char
#1 1 5 9 4 8 12 2.5 6.5 10.5
#2 2 6 10 3 7 11 2.5 6.5 10.5
#3 3 7 11 2 6 10 2.5 6.5 10.5
#4 4 8 12 1 5 9 2.5 6.5 10.5
数据
df <- data.frame(abc_alpha, abc_beta, abc_char, xyz_alpha, xyz_beta, xyz_char)
推荐阅读
- rest - 如何使用 PowerShell 通过 REST API 将 CSV 文件附加到 Service Now 事件?
- linux - PostgreSQL - 使用 shell 脚本插入名称为关键字的列
- python - Matplotlib 散点/等高线混合图
- c# - set 和 setCookie 方法有什么区别
- python - 如何合并所有子目录中同名的文本文件。合并数据将根据日期和时间存储?
- fortran - 将矩阵打印到文件中
- javascript - 滚动事件触发太早
- javascript - 如何在 JS 中创建一个简单的倒数计时器?
- oauth - 如果有人窃取了 Oath2 流程中的授权代码会发生什么
- unit-testing - 让 Julia 测试套件在运行结束时报告所有错误消息