假设我的数据框有几行,如下所示:
User Lab Score
A 1 5
A 2 6
A 4 7
B 1 3
B 3 4
C 2 5
然后,对于实验1,我想将得分除以5,对于实验2,我想将得分除以8,对于实验3,我想将得分除以7,对于实验室4我想要将得分除以9。 我该怎么做呢?
答案 0 :(得分:9)
对于像这样的数据转换任务,请使用ifelse
,这是一种基于条件从不同结果中进行选择的矢量化形式。
df$Score <- with(df, ifelse(Lab == 1, Score/5,
ifelse(Lab == 2, Score/8,
ifelse(Lab == 3, Score/7, Score/9))))
(假设您只有4个实验室。)
答案 1 :(得分:2)
这是一个使用merge
的简洁易用的解决方案。
dat1 <- data.frame(Lab=c(1,2,3,4),
coef = c(1/5,1/8,1/7,1/9))
dt.m <- merge(dat,dat1,all.x=TRUE)
dt.m$coef[is.na(dt.m $coef)] <- 1 ## default value
dtt <- transform(dt.m,newScore=Score*coef)
Lab User Score coef newScore
1 1 A 5 0.2000000 1.0000000
2 1 B 3 0.2000000 0.6000000
3 2 A 6 0.1250000 0.7500000
4 2 C 5 0.1250000 0.6250000
5 3 B 4 0.1428571 0.5714286
6 4 A 7 0.1111111 0.7777778
编辑如果您想获得与原始数据相同的订单,结构:
dtt[order(dtt$User),c('User','Lab','Score','newScore')]
User Lab Score newScore
1 A 1 5 1.0000000
3 A 2 6 0.7500000
6 A 4 7 0.7777778
2 B 1 3 0.6000000
5 B 3 4 0.5714286
4 C 2 5 0.6250000
答案 2 :(得分:0)
这可能非常不正统,但也比许多ifelse
更容易阅读。 factor
您的“实验室”值,将除数指定为labels
,并按正常方式划分。假设data.frame
被称为“mydf”:
within(mydf, {
temp <- as.numeric(as.character(factor(Lab, levels=c(1, 2, 3, 4),
labels=c(5, 8, 7, 9))))
Score <- Score/temp
rm(temp)
})
# User Lab Score
# 1 A 1 1.0000000
# 2 A 2 0.7500000
# 3 A 4 0.7777778
# 4 B 1 0.6000000
# 5 B 3 0.5714286
# 6 C 2 0.6250000