如何以更简单的方式分配值并总结 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)]
我 运行 我的代码,我得到了一个数据框
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)]