我有一个大约200列的数据框,如下所示
1376 PSEN1 1.4057115 0.1254332 0.1254332
1377 PSMA2 -1.6285915 1.2343333 1.2343333
1378 PSMA3 0.7547530 -3.0000000 0.8299074
1379 PSMA4 -0.9455922 0.0000000 -1.6285915
1380 PSMA6 0.8299074 32.0065000 1.5311143
1381 PSMB2 -2.0481873 0.0000000 -2.4958000
1382 PSMB3 1.5311188 2.4958000 0.0000456
1383 PSMB5 1.5259254 5.0000456 3.6538010
1384 PSMB7 0.6538010 5.0654087 2.4934745
我需要为正输入指定值2,为负值指定-2,然后执行行和。是否有任何有效的方法来执行此操作,否则我需要运行循环并检查条件,然后通过编写长代码来分配值。
所需的输出类似
1376 PSEN1 2 2 2 6
1377 PSMA2 -2 2 2 2
1378 PSMA3 2 -2 2 2
此处仅显示三行。感谢
答案 0 :(得分:3)
假设我们想要更改除前两列之外的所有列中的值,请获取列sign
(df1[-(1:2)]
)并乘以2.如果我们需要创建新列(' newCol'),然后对更改的列值使用rowSums
。
df1[-(1:2)] <- sign(df1[-(1:2)])*2
df1$newCol <- rowSums(df1[-(1:2)])
head(df1,3)
# V1 V2 V3 V4 V5 newCol
#1 1376 PSEN1 2 2 2 6
#2 1377 PSMA2 -2 2 2 2
#3 1378 PSMA3 2 -2 2 2
注意:我根据预期输出将值替换为新值。如果需要,您可以复制原始数据集。
或使用Reduce
df1$newCol <- Reduce(`+`, df1[-(1:2)])
如果0
属于正类别,
rowSums(`dim<-`(c(-2, 2)[(df1[-(1:2)]>=0)+1L], dim(df1[-(1:2)])))
#[1] 6 2 2 -2 6 -2 6 6 6
或者基于原始解决方案,
rowSums((sign(df1[-(1:2)]) + !df1[-(1:2)])*2)
#[1] 6 2 2 -2 6 -2 6 6 6
df1 <- structure(list(V1 = 1376:1384, V2 = c("PSEN1", "PSMA2",
"PSMA3",
"PSMA4", "PSMA6", "PSMB2", "PSMB3", "PSMB5", "PSMB7"),
V3 = c(1.4057115,
-1.6285915, 0.754753, -0.9455922, 0.8299074, -2.0481873, 1.5311188,
1.5259254, 0.653801), V4 = c(0.1254332, 1.2343333, -3, 0, 32.0065,
0, 2.4958, 5.0000456, 5.0654087), V5 = c(0.1254332, 1.2343333,
0.8299074, -1.6285915, 1.5311143, -2.4958, 4.56e-05, 3.653801,
2.4934745)), .Names = c("V1", "V2", "V3", "V4", "V5"),
class = "data.frame", row.names = c(NA, -9L))
答案 1 :(得分:3)
在一行中的另一种方式,并且不更改df中的值,假设0为0的条目分配:
rowSums(ifelse(df1[, 3:5]==0, 0, ifelse(df1[, 3:5]>0, 2, -2)))
# [1] 6 2 2 -2 6 -2 6 6 6
注意:如果您需要更改df1中的值,您可以执行以下操作:
df1[, 3:5] <- ifelse(df1[, 3:5]==0, 0, ifelse(df1[, 3:5]>0, 2, -2)); rowSums(df1[, 3:5])