如何以更简单的方式分配值并总结 R 中的行?

How to assign value and sum up rows in R in a simpler way?

我 运行 我的代码,我得到了一个数据框

            V1 V2 V3 V4
1        CCL5  P  0  0
2      CYP2A6  M  A  A
3      CYP2E1  P  A  P
4        DDR1  P  0  P
5       EPHB3  A  P  A
6       ESRRA  A  A  P
7      GUCA1A  A  0  0
8       HSPA6  A  0  A
9  NCRNA00152  A  0  0
10       PAX8  P  0  P
11     PTPN21  P  0  A
12       RFC2  P  0  P
13     SCARB1  P  P  P
14       THRA  P  0  A
15     TTLL12  P  0  P
16       UBA7  P  0  P
17      WFDC2  P  0  0

为了进一步处理数据帧,我 运行 此代码

    replace <- function(d1)
    {
      rows=nrow(d1)
      cols=ncol(d1)
      for(i in 1:rows)
      {
        for (j in 2:cols)
        {
          if (d1[i,j]=="P")
            d1[i,j] = 2
          else if(d1[i,j]=="A")
            d1[i,j]= -2
          else if(d1[i,j]=="M")
            d1[i,j]= 0
        }
      }

      for(i in 1:rows)
      {
        j=2
        sum=0
        while(j<=cols)
        {
          sum1=as.numeric(d1[i,j])
          sum=sum+sum1
          j=j+1 
        }
        d1[i,cols+1]=sum
        if(sum > 0)
          d1[i,cols+2]="P"
        else if(sum < 0)
          d1[i,cols+2]="A"
        else if(sum==0)
          d1[i,cols+2]="0"
      }
      return(d1)
    }
replace(d1)

所以我的数据框应该是这样的。我用 2 替换 P,用 -2 替换 A,用 0 替换 M,然后在其他列中求和。在第 5 列中,如果值比最后一列中的 P 为正,如果为负则为 A,对于 0,则为 0。

           V1 V2 V3 V4 V5 V6
1        CCL5  2  0  0  2  P
2      CYP2A6  0 -2 -2 -4  A
3      CYP2E1  2 -2  2  2  P
4        DDR1  2  0  2  4  P
5       EPHB3 -2  2 -2 -2  A
6       ESRRA -2 -2  2 -2  A
7      GUCA1A -2  0  0 -2  A
8       HSPA6 -2  0 -2 -4  A
9  NCRNA00152 -2  0  0 -2  A
10       PAX8  2  0  2  4  P
11     PTPN21  2  0 -2  0  0
12       RFC2  2  0  2  4  P
13     SCARB1  2  2  2  6  P
14       THRA  2  0 -2  0  0
15     TTLL12  2  0  2  4  P
16       UBA7  2  0  2  4  P
17      WFDC2  2  0  0  2  P

我认为我的代码很长,无法完成这个简单的任务。有没有办法让它变得非常简单。非常感谢。

已编辑:在我的数据框中可能有超过 200 列或更多列。

你试过了吗

d1[d1 == "P"] <- 2
d1[d1 == "A"] <- -2
d1[d1 == "M"] <- 0

然后你可以取 d1[ 2:5] 的行和然后放在最后一列。

最后再次替换为

d1[,6][d1[,6] > 0] <- "P"
d1[,6][d1[,6] < 0] <- "A"

假设 df 是您的 data.frame。首先是将character中的所有factors进行转换。然后替换为所需的值 - 我使用深度函数式编程方法执行此操作,因此对您的 df 没有副作用 :) 并将所需的列转换为 numeric:

library(functional)

df[] = lapply(df, as.character)

f   = function(df, u, target) {df[df==u]=target; df}
fs  = Map(function(x,y) Curry(f, u=x, target=y), c('P','A','M'),c('2','-2','0'))
df1 = Reduce(Compose, fs)(df)

df1 = transform(df1, V5=rowSums(apply(df1[,2:4], 2, as.numeric)))
transform(df1, V6=ifelse(df1$V5>0, 'P', ifelse(df1$V5<0,'A','0')))
#      V1 V2 V3 V4 V5 V6
#1   CCL5  2  0  0  2  P
#2 CYP2A6  0 -2 -2 -4  A
#3 CYP2E1  2 -2  2  2  P
#4   DDR1  2  0  2  4  P

数据

df = data.frame(V1=c("CCL5","CYP2A6","CYP2E1","DDR1"), V2=c("P",'M','P','P'), V3=c('0','A','A','0'), V4=c('0','A','P','P'))

基于命名向量的方法:

m  <- c(P=2, A=-2, '0'=0, M=0)
m.back <- c(P=1, A=-1, '0'=0)

d1$V5 <- with(d1, m[V2] + m[V3] + m[V4])
d1$V6 <- names(m.back)[match(sign(d1$V5), m.back)]

其中 d1 是您的数据集。

[更新] 如果您想对数据集中除第一列以外的所有列求和:

m  <- c(P=2, A=-2, '0'=0, M=0)
m.back <- c(P=1, A=-1, '0'=0)

converted <- m[unlist(d1[,-1])]

d1$sum <- rowSums(matrix(converted,ncol=ncol(d1)-1))

d1$symbolic.sum <- names(m.back)[match(sign(d1$sum), m.back)]