R中的条件替换
Conditional replacement in R
我在 R 中有一个如下所示的数据框:
Genes snps X0 X1 X2 X3
2 WASH7P 1_14677 0 2 2 2
3 WASH7P 1_14684 0 1 2 0
4 WASH7P 1_14685 0 0 0 0
是否可以进行条件替换,如果 int 2 在 X0-X3 列中的频率 > 0.5,则可以将 2 替换为 0,将 0 替换为 2?
这样新的数据框是:
Genes snps X0 X1 X2 X3
2 WASH7P 1_14677 2 0 0 0
3 WASH7P 1_14684 0 1 2 0
4 WASH7P 1_14685 0 0 0 0
提前致谢!
使用R
,我们可以为以'X' ('i1') 开头的列名创建索引。然后,我们根据 'X' 列中为 2 的值的 rowMeans
大于 0.5 的条件获取行索引。我们根据 row/column 索引对 'df1' 进行子集化,遍历列 (lapply(...
),然后使用recode
来自 library(car)
。将输出分配回 'df1' 的 rows/columns 的子集。
library(car)
i1 <- grep('^X', names(df1))
i2 <- rowMeans(df1[i1]==2)> 0.5
df1[i1][i2,] <- lapply(df1[i1][i2,], recode, '2=0;0=2')
df1
# Genes snps X0 X1 X2 X3
#2 WASH7P 1_14677 2 0 0 0
#3 WASH7P 1_14684 0 1 2 0
#4 WASH7P 1_14685 0 0 0 0
数据
df1 <- structure(list(Genes = c("WASH7P", "WASH7P", "WASH7P"),
snps = c("1_14677",
"1_14684", "1_14685"), X0 = c(0L, 0L, 0L), X1 = c(2L, 1L, 0L),
X2 = c(2L, 2L, 0L), X3 = c(2L, 0L, 0L)), .Names = c("Genes",
"snps", "X0", "X1", "X2", "X3"), class = "data.frame",
row.names = c("2", "3", "4"))
另一种可能的方法:
cbind(df[1:2], t(as.data.frame(apply(df[3:ncol(df)], 1, function(x) {
if(mean(x == 2) > .5) {
x[x==0] <- 4
x - 2} else x}))))
# Genes snps X0 X1 X2 X3
#2 WASH7P 1_14677 2 0 0 0
#3 WASH7P 1_14684 0 1 2 0
#4 WASH7P 1_14685 0 0 0 0
在函数内部,4
被分配给了 0
值。然后从行中减去 2
,留下所需的输出。
如果数据框的名称结构发生变化,请使用@akrun的列搜索方法。或者,如果 2
和 0
只是玩具示例并且重新编码要复杂得多,请使用 akrun 的值规范答案。这只是另一种没有包的方法。
我在 R 中有一个如下所示的数据框:
Genes snps X0 X1 X2 X3
2 WASH7P 1_14677 0 2 2 2
3 WASH7P 1_14684 0 1 2 0
4 WASH7P 1_14685 0 0 0 0
是否可以进行条件替换,如果 int 2 在 X0-X3 列中的频率 > 0.5,则可以将 2 替换为 0,将 0 替换为 2? 这样新的数据框是:
Genes snps X0 X1 X2 X3
2 WASH7P 1_14677 2 0 0 0
3 WASH7P 1_14684 0 1 2 0
4 WASH7P 1_14685 0 0 0 0
提前致谢!
使用R
,我们可以为以'X' ('i1') 开头的列名创建索引。然后,我们根据 'X' 列中为 2 的值的 rowMeans
大于 0.5 的条件获取行索引。我们根据 row/column 索引对 'df1' 进行子集化,遍历列 (lapply(...
),然后使用recode
来自 library(car)
。将输出分配回 'df1' 的 rows/columns 的子集。
library(car)
i1 <- grep('^X', names(df1))
i2 <- rowMeans(df1[i1]==2)> 0.5
df1[i1][i2,] <- lapply(df1[i1][i2,], recode, '2=0;0=2')
df1
# Genes snps X0 X1 X2 X3
#2 WASH7P 1_14677 2 0 0 0
#3 WASH7P 1_14684 0 1 2 0
#4 WASH7P 1_14685 0 0 0 0
数据
df1 <- structure(list(Genes = c("WASH7P", "WASH7P", "WASH7P"),
snps = c("1_14677",
"1_14684", "1_14685"), X0 = c(0L, 0L, 0L), X1 = c(2L, 1L, 0L),
X2 = c(2L, 2L, 0L), X3 = c(2L, 0L, 0L)), .Names = c("Genes",
"snps", "X0", "X1", "X2", "X3"), class = "data.frame",
row.names = c("2", "3", "4"))
另一种可能的方法:
cbind(df[1:2], t(as.data.frame(apply(df[3:ncol(df)], 1, function(x) {
if(mean(x == 2) > .5) {
x[x==0] <- 4
x - 2} else x}))))
# Genes snps X0 X1 X2 X3
#2 WASH7P 1_14677 2 0 0 0
#3 WASH7P 1_14684 0 1 2 0
#4 WASH7P 1_14685 0 0 0 0
在函数内部,4
被分配给了 0
值。然后从行中减去 2
,留下所需的输出。
如果数据框的名称结构发生变化,请使用@akrun的列搜索方法。或者,如果 2
和 0
只是玩具示例并且重新编码要复杂得多,请使用 akrun 的值规范答案。这只是另一种没有包的方法。