2014-01-05 26 views
0

在模拟数据基于值的数据帧的列(多个)条件的变化设定到其他列中

n = 50 
set.seed(378) 
df <- data.frame(
    age = sample(c(20:90), n, rep = T), 
    sex = sample(c("m", "f"), n, rep = T, prob = c(0.55, 0.45)), 
    smoker = sample(c("never", "former", "active"), n, rep = T, prob = c(0.4, 0.45, 0.15)), 
    py = abs(rnorm(n, 25, 10)), 
    yrsquit = abs (rnorm (n, 10,2)), 
    outcome = as.factor(sample(c(0, 1), n, rep = T, prob = c(0.8, 0.2))) 
) 

我需要引入的结果组之间有些不平衡(1 =疾病,0 =无疾病) 。例如,患有该疾病的受试者年龄更大并且更可能是男性。我试图

df1 <- within(df, sapply(length(outcome), function(x) { 
if (outcome[x] == 1) { 
    age[x] <- age[x] + 15 
    sex[x] <- sample(c("m","f"), prob=c(0.8,0.2)) 
} 
})) 

但如图

tapply(df$sex, df$outcome, length) 
tapply(df1$sex, df$outcome, length) 
tapply(df$age, df$outcome, mean) 
tapply(df1$age, df$outcome, mean) 

回答

2

within采用sapply像您期望的不工作没有什么区别。函数within只使用返回值sapply。但在你的代码中,sapply返回NULL。因此,within不会修改数据帧。

这里是修改数据帧没有环或sapply更简单的方法:

idx <- df$outcome == "1" 
df1 <- within(df, {age[idx] <- age[idx] + 15; 
        sex[idx] <- sample(c("m", "f"), sum(idx), 
             replace = TRUE, prob = c(0.8, 0.2))}) 

现在,数据帧是不同的:

> tapply(df$age, df$outcome, mean) 
     0  1 
60.46341 57.55556 
> tapply(df1$age, df$outcome, mean) 
     0  1 
60.46341 72.55556 

> tapply(df$sex, df$outcome, summary) 
$`0` 
f m 
24 17 

$`1` 
f m 
2 7 

> tapply(df1$sex, df$outcome, summary) 
$`0` 
f m 
24 17 

$`1` 
f m 
1 8