在R中执行lappy时忽略特定级别

在R中执行lappy时忽略特定级别,r,replace,levels,R,Replace,Levels,我在R中有一个数据帧(500OB,40000个变量),其中所有列都由一个或两个字母组成,中间点缀着“1”和“3”。例如,mydata[45:50,20:25] 45 C A 3 T C C 46 C G T C C

我在R中有一个数据帧(500OB,40000个变量),其中所有列都由一个或两个字母组成,中间点缀着“1”和“3”。例如,
mydata[45:50,20:25]

45             C             A             3             T             C             C
46             C             G             T             C             C             A
47             C             A             G             T             C             C
48             1             A             T             3             C             3
49             C             A             G             T             C             C
50             T             A             T             C             C             A
我只想替换字母,不想替换数字。我的目标是根据字母的频率将其替换为“0”或“2”。因此,最频繁的字母变为“0”,最不频繁的字母变为“2”。如果只有一个字母,它将变成“0”

我可以在不忽略散布的“1”和“3”的情况下通过以下方式实现这一点:

data.frame(lappy(mydata[45:50,20:25],函数(x){as.numeric(factor(x,levels=names(sort(-table(x ')))}))

这将产生:

1             1             1             3             1             1             1
2             1             2             1             2             1             2
3             1             1             2             1             1             1
4             2             1             1             3             1             3
5             1             1             2             1             1             1
6             3             1             1             2             1             2
但是,我希望能够做到这一点,同时忽略原始数据帧中的“1”和“3”


谢谢你的帮助。谢谢。

我会在这里使用
矩阵

使用
grep
我们制作了一个
频率表
,我们
对其负值进行排序
,然后减去一得到零。因为我不确定在打领带的情况下你想要什么,所以我选择了
“first”
来获得一个整数(有关选项,请参见
?rank

然后我们对频率上的字母进行匹配。最后,我们使用
type.convert
转换回数据帧以获得数字格式

m <- as.matrix(d)

ftb <- table(grep("[\\p{Lu}]", m, perl=TRUE, value=TRUE))
ftb <- rank(-ftb, ties.method="first") - 1

m.res <- apply(m, 1:2, function(x) ifelse(x %in% names(ftb), ftb[match(x, names(ftb))], x))
d.res <- type.convert(as.data.frame(m.res))
d.res
#   V1 V2 V3 V4 V5 V6 V7
# 1 45  0  1  3  2  0  0
# 2 46  0  3  2  0  0  1
# 3 47  0  1  3  2  0  0
# 4 48  1  1  2  3  0  3
# 5 49  0  1  3  2  0  0
# 6 50  2  1  2  0  0  1

数据:


d感谢您的回复。我想我的问题可能不是很清楚。根据整个矩阵中的频率,您的解决方案目前将字母替换为0和2。我希望根据每列字母出现的频率,将它们替换为0和2。@C24只需将其放入
lappy
,请参见编辑。感谢您的回复。现在它将重点放在列上。但是,我希望最频繁的字母被重新编码为“0”,最不频繁的字母被重新编码为“2”。目前,您的解决方案似乎是将最频繁的字母改为“0”,但将最不频繁的字母改为“1”。例如:V7中的数字(从上到下)应为:“0”、“2”、“0”、“3”、“0”、“2”,而V2中的数字应为:“0”、“0”、“0”、“1”、“0”、“2”“我提供了一个指向完整数据集的链接,我想用它来实现这一点,以防有所帮助:@C24您是否阅读了
?rank
?中的ties部分?我阅读了它,我不明白ties方法如何为我提供解决方案。事实上,我都试过了,但似乎都不管用。如果你能详细说明,我将不胜感激?我想我有一个变通方法,包括在解决方案之前和之后替换值,但我更喜欢一个更优雅的方法。
f <- 2
d[-1] <- lapply(d[-1], function(x) {
  ftb <- (rank(-table(grep("[\\p{Lu}]", x, perl=TRUE, value=TRUE)),
              ties.method="first") - 1)*f
  stopifnot(length(ftb) <= 2)
  x <- ifelse(x %in% names(ftb), ftb[match(x, names(ftb))], x)
  as.numeric(x)
})
d
#   V1 V2 V3 V4 V5 V6 V7
# 1 45  0  0  3  0  0  0
# 2 46  0  2  0  2  0  2
# 3 47  0  0  2  0  0  0
# 4 48  1  0  0  3  0  3
# 5 49  0  0  2  0  0  0
# 6 50  2  0  0  2  0  2
d <- structure(list(V1 = 45:50, V2 = c("C", "C", "C", "1", "C", "T"
), V3 = c("A", "G", "A", "A", "A", "A"), V4 = c("3", "T", "G", 
"T", "G", "T"), V5 = c("T", "C", "T", "3", "T", "C"), V6 = c("C", 
"C", "C", "C", "C", "C"), V7 = c("C", "A", "C", "3", "C", "A"
)), class = "data.frame", row.names = c(NA, -6L))