将因子分配给数据帧

时间:2011-06-13 13:23:39

标签: 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
在上述数据框中,我希望添加一个名为“治疗”的第三列,其中受试者被分配到两个级别“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  

提前感谢您的帮助。

4 个答案:

答案 0 :(得分: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))

这给出了:

R> Treat
  subject treatment
1       1         b
2       4         a
3       2         b
4       6         b

修改

如果已预先指定治疗,则只需手动创建Treat数据框;

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

如果你有很多这样做,你可以使用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

答案 1 :(得分: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))

编辑 - 解决您的评论

鉴于您想指定哪个主题被分配到哪个主题,Gavin对merge的建议是正确的。我首先会创建一个新的data.frame,其中包含每个唯一主题的一条记录,分配它们的处理,然后将它们合并在一起:

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

请注意,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"))

答案 2 :(得分:2)

我假设您有一些关键如何转换此数据,例如1,6 =&gt; a,4,2 =&gt; b。 然后ifelse%in%混合应该完成工作:

df$treatment<-factor(ifelse(df$subject%in%c('1','6'),'a','b'))

更通用的选项是复制此因子并更改其级别,但详细信息取决于您如何存储字典。简单的例子:

x<-df$subject; levels(x)<-c('a','b','b','a')
x->df$treatment

(在两个例子中,我都认为主题是一个因素)

答案 3 :(得分:0)

另一种方法可能是编写一个特殊功能来决定对受试者的治疗,并将该功能应用于受试者以创建一个新的治疗栏。

以下是代码:

> head(data)
  subject rate treat
1       1   15     a
2       2   20     b
3       4    8     a
4       6   16     b
5       1   19     a
6       2    5     b

输出:

{{1}}