r - 根据配对列替换值
问题描述
我有一个数据框,每个样本有两列(n > 1000 个样本):
df <- data.frame(
"sample1.a" = 1:5, "sample1.b" = 2,
"sample2.a" = 2:6, "sample2.b" = c(1, 3, 3, 3, 3),
"sample3.a" = 3:7, "sample3.b" = 2)
如果 .b 列为零,则 .a 列的对应值应设置为 NA。
我想在 colnames(不带后缀)上编写一个函数来过滤每对列和条件交换值。有没有基于 tidyverse 的更简单的方法?
解决方案
我们可以将 data.frame 拆分为 data.frames 列表并在base R
df1 <- do.call(cbind, lapply(split.default(df,
sub("\\..*", "", names(df))), function(x) {
x[,1][x[2] == 0] <- NA
x}))
或者另一种选择是Map
acols <- endsWith(names(df), "a")
bcols <- endsWith(names(df), "b")
df[acols] <- Map(function(x, y) replace(x, y == 0, NA), df[acols], df[bcols])
或者如果列与 'a'、'b' 列交替,则使用逻辑索引进行回收,创建具有 'b' 列的逻辑矩阵并将 'a' 列中的相应值分配给 NA
df[c(TRUE, FALSE)][df[c(FALSE, TRUE)] == 0] <- NA
或tidyverse
通过重塑为“长”pivot_longer
格式NA
(pivot_wider
library(dplyr)
library(tidyr)
df %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_sep="\\.",
names_to = c('group', '.value')) %>%
mutate(a = na_if(b, a == 0)) %>%
pivot_wider(names_from = group, values_from = c(a, b)) %>%
select(-rn)
# A tibble: 5 x 6
# a_sample1 a_sample2 a_sample3 b_sample1 b_sample2 b_sample3
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 2 1 2 2 1 2
#2 2 3 2 2 3 2
#3 2 3 2 2 3 2
#4 2 3 2 2 3 2
#5 2 3 2 2 3 2
推荐阅读
- python - 如何使用 scapy 计算数据包
- regex - RegEx在Powershell中匹配两个字符串之间的字符串
- android - 导入不是有效的资源名称(保留的 Java 关键字)
- android - 无法更改演员在屏幕上的位置
- c++ - 尝试用 C++ 创建一个基本的计算器;获得大量编译错误
- postgresql - PostgresSQL 转储加载成功,但数据库上没有写入任何内容
- javascript - 导入 Moment.js 时 JavaScript 语法错误
- c++ - 条件运算符的值类别
- reactjs - 在反应应用程序中收到“尝试导入错误:”
- testing - 如何创建一个虚拟组件以在 Ember 集成测试中使用?