如何用R中的字符替换数值?

如何用R中的字符替换数值?,r,R,我有一个这样的文件 "1" 10 2 0 0 0 0 0 0 0 0 0 0 0 4 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 "2" 10 3 6 17 11 15 8 17 14 1 42 21 22 15 9 9 17 12 9 16 4 8 12 29 23 11 0 0 0 0 "3" 10 4 39 39 14 33 16 23 37 21 29 22 46 26 16 26 21 22 21 10 16 3 10 14 20 12 6 0 0 0 "4" 10

我有一个这样的文件

"1" 10 2 0 0 0 0 0 0 0 0 0 0 0 4 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0
"2" 10 3 6 17 11 15 8 17 14 1 42 21 22 15 9 9 17 12 9 16 4 8 12 29 23 11 0 0 0 0
"3" 10 4 39 39 14 33 16 23 37 21 29 22 46 26 16 26 21 22 21 10 16 3 10 14 20 12 6 0 0 0
"4" 100 18 0 0 0 1 0 0 0 0 0 0 2 0 0 1 0 2 8 5 2 1 2 4 9 6 4 3 0 0
.....................
我想做的是,用字符替换第4列之后的值,即,如果值在0到10之间,那么它将被字符“a”替换,如果值在10到20之间,那么它将被字符b替换,依此类推

例如,输出文件的格式为

"1" 10 2 0 0 0 0 0 0 0 0 0 0 0 a 0 0 a 0 0 0 0 0 a 0 0 0 0 0 0 0
.............................
我怎么能在R里做呢?是否有某种方法可以自动分配字符,因为目前我使用两个for循环,并按范围对值进行harcoding

编辑:我的方法:

> for ( i in 1:nrow(x) )
+     for ( j in j:ncol(x) )
+         {
+             if (x[i,j] < 10 && x[i,j] > 0 )
+                 x[i,j] = a
+             else if ( x[i,j] < 20 && x[i,j] > 10 )
+                 x[i,j] = b
+         }
>用于(1中的i:nrow(x))
+对于(j中的j:ncol(x))
+         {
+如果(x[i,j]<10&&x[i,j]>0)
+x[i,j]=a
+else如果(x[i,j]<20&&x[i,j]>10)
+x[i,j]=b
+         }

以上是我的做法。这在条件中显示了一个错误,我知道这将花费很多时间,因为它涉及到使用两个for循环

一种可能的解决方案是创建一个虚拟数据集进行匹配,然后将所有非零值与之匹配(假设
df
是您的数据集)


matchData您可以使用ascii码和基于您的值/10的偏移量(无余数)

输出:

> char10
[1] "b" "a" "0" "b" "c" "b" "0" "0"

我认为以下几点很接近,只是一个快速的回答,希望能帮助你。您必须应用此方法才能对整个数据帧执行此操作。还有我在这里没有处理的强制,所以当在一行上测试时,所有的东西都被强制成一个字符

基本思想是,如果你想让1-10对应于“a”,11-20对应于“b”,那么我们可以将数字除以10,然后调用天花板。1-10映射到1,11-20映射到2,依此类推。字母[1]映射到“a”,字母[2]映射到“b”,等等,因此我们得到了所需的功能

 #everything coerced to char, I know
 testVect<-c("2", 10, 3, 6, 17, 11, 15, 8 ,17, 14, 1, 42, 21, 22, 15, 9, 9, 17, 12, 9, 16, 4, 8, 12 ,29, 23, 11, 0, 0 ,0 ,0)

 testAfter4<-sapply(testVect[4:length(testVect)], 
        function(entry) {
              ifelse(entry==0, 0, letters[ceiling(as.numeric(entry)/10)])
         } )
 #need to cast entry back to numeric as it was coerced to char when initializing testVect

 testVect[4:length(testVect)]<-testAfter4

 testVect
 #[1] "2"  "10" "3"  "a"  "b"  "b"  "b"  "a"  "b"  "b"  "a"  "e"  "c"  "c"  "b" 
 #[16] "a"  "a"  "b"  "b"  "a"  "b"  "a"  "a"  "b"  "c"  "c"  "b"  "0"  "0"  "0" 
 #[31] "0"
#我知道一切都是被强迫的

testVectPlease从
dput
output提供数据。另外,到目前为止你使用了什么代码?你有什么错误吗?您在解决自己的问题时没有表现出任何努力。您期望的输出与您描述的不匹配。为什么
4
d
取代而不是
a
?@David,我的错。我已经编辑过了。抱歉。如果您只是使用acsii值,我建议您使用内置的
字母
向量,而不是
rawToChar
。例如,
字母[1]=“a”
字母[2]=“b”
,等等。。。所以
asc10=function(x){letters[1+(x%/%10)]}
或者类似的(没有测试)好主意。我想一定有更好的办法。那么我也不需要
strsplit
步骤。我将在此基础上添加一个解决方案。阅读答案,我想这只是David答案的另一种形式,只是不需要创建虚拟集
> char10
[1] "b" "a" "0" "b" "c" "b" "0" "0"
 #everything coerced to char, I know
 testVect<-c("2", 10, 3, 6, 17, 11, 15, 8 ,17, 14, 1, 42, 21, 22, 15, 9, 9, 17, 12, 9, 16, 4, 8, 12 ,29, 23, 11, 0, 0 ,0 ,0)

 testAfter4<-sapply(testVect[4:length(testVect)], 
        function(entry) {
              ifelse(entry==0, 0, letters[ceiling(as.numeric(entry)/10)])
         } )
 #need to cast entry back to numeric as it was coerced to char when initializing testVect

 testVect[4:length(testVect)]<-testAfter4

 testVect
 #[1] "2"  "10" "3"  "a"  "b"  "b"  "b"  "a"  "b"  "b"  "a"  "e"  "c"  "c"  "b" 
 #[16] "a"  "a"  "b"  "b"  "a"  "b"  "a"  "a"  "b"  "c"  "c"  "b"  "0"  "0"  "0" 
 #[31] "0"