3

假设我有一个包含几行的数据框,如下所示:

        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 分。我该怎么做呢?

4

3 回答 3

11

对于这样的数据转换任务,请使用ifelse,这是一种基于条件从不同结果中进行选择的矢量化形式。

df$Score <- with(df, ifelse(Lab == 1, Score/5,
                     ifelse(Lab == 2, Score/8,
                     ifelse(Lab == 3, Score/7, Score/9))))

(这假设您只有 4 个实验室。)

于 2013-07-08T15:48:05.603 回答
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
于 2013-07-08T16:03:28.220 回答
0

ifelse这可能是非常非正统的,但也可能比很多s更容易阅读。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
于 2013-07-08T15:53:13.677 回答