将因子分配给数据帧

Rod*_*ger 2 r

我想在数据框中添加一列,它将编码一个因子的特定级别.例如

subject  rate
1          12
1          10 
1          13
4          4
4          6
4          12
2          9
2          2
2          5
6          17
6          10
6          1
Run Code Online (Sandbox Code Playgroud)

在上述数据框中,我希望添加一个名为"处理"的第三列,其中主题被分配给两个级别"a"或"b"中的一个.例如下面

subject  rate  treatment
1          12      a
1          10      a
1          13      a
4          4       b
4          6       b
4          12      b
2          9       b
2          2       b
2          5       b 
6          17      a
6          10      a
6          1       a  
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助.

Rei*_*son 5

如果你想随机分配治疗,这将做到:

## subject IDs
subj <- with(dat, unique(subject))

## how many treatment levels?
ntreat <- 2

## sample an identifier for the treaments
set.seed(47)
treats <- sample(letters[seq_len(ntreat)], length(subj), replace = TRUE)

## stick this into a subject/treatment data frame
Treat <- data.frame(cbind(subject = subj, treatment = treats))
Run Code Online (Sandbox Code Playgroud)

这给出了:

R> Treat
  subject treatment
1       1         b
2       4         a
3       2         b
4       6         b
Run Code Online (Sandbox Code Playgroud)

编辑:

如果已经预先分配了治疗,那么只需Treat手动创建数据框;

Treat <- data.frame(subject = c(1,4,2,6), treatment = c("a","b","b","a"))
Run Code Online (Sandbox Code Playgroud)

如果你有很多这样做,你可以使用像seq()和的函数rep(),加上内置的letters常量来加速"数据输入".

结束编辑

我们现在可以在与原始数据合并中使用此数据框来插入treatment相应的数据框subject,使用merge():

R> merge(dat, Treat)
   subject rate treatment
1        1   12         b
2        1   10         b
3        1   13         b
4        2    9         b
5        2    2         b
6        2    5         b
7        4    4         a
8        4    6         a
9        4   12         a
10       6   17         b
11       6   10         b
12       6    1         b
Run Code Online (Sandbox Code Playgroud)


Cha*_*ase 5

这是使用plyr包的另一种方法:

library(plyr)

#Make some fake data
set.seed(1)
dat <- data.frame(subject = rep(c(1,4,2,6), each = 3), rate = sample(1:20, 12, TRUE))

set.seed(1)
#Assign treatment based on the subject ID. This does not ensure that you will get
#at least one subject in each treatment group.
ddply(dat, "subject", transform, treatment = sample(letters[1:2], TRUE))
Run Code Online (Sandbox Code Playgroud)

编辑 - 解决您的评论

鉴于你想指定哪个主题被分配到哪个治疗,加文的建议merge就是现场.我首先会创建一个新的data.frame,其中包含每个唯一主题的一条记录,分配它们的处理,然后将它们合并在一起:

treatments <- data.frame(subject = unique(dat$subject), treats = c("a", "b", "b", "a"))
merge(dat, treatments)
Run Code Online (Sandbox Code Playgroud)

注意,顺序unique(dat$subject)是1,4,2,6,它对应于原始data.frame中值的顺序.如果您的真实问题包含四个以上的主题,您可能需要考虑一种更自动的方式来分配治疗组.我过去使用过的一种方法是为每个受访者分配一个随机数,然后根据该随机数的给定阈值分配组.它与上面的方法基本相同,但可以确保您在每个组中获得相同的数字.例如:

dat <- ddply(dat, "subject", transform, treatment = runif(1))
dat <- within(dat, treatment <- ifelse(treatment < quantile(treatment, 0.5),"a", "b"))
Run Code Online (Sandbox Code Playgroud)