2012-02-20 55 views
0

是这样的模拟数据:定义因素,其水平依赖于另一个变量

set.seed(20120220) 
x <- c(rep("a", 4), rep("b", 4)) 
y <- c(sample(c(1, 2), 8, replace = TRUE)) 
z <- data.frame(cbind(x, y)) 

数据帧z看起来就像这样:

x y 
1 a 1 
2 a 1 
3 a 1 
4 a 2 
5 b 2 
6 b 1 
7 b 2 
8 b 2 

我想运行到factor(z$y, levels = 1:2, labels = c("alpha", "beta"))一个类似于,但我不不想让每个1变成alpha,并且每个2变成beta。我希望这发生只有x = a。如果x = b,我想1变成gamma2变成delta

换句话说,我希望我的数据帧,看起来像这样:

x y 
1 a alpha 
2 a alpha 
3 a alpha 
4 a beta 
5 b delta 
6 b gamma 
7 b delta 
8 b delta 

这是我想出了这么远:

for (i in 1:nrow(z)) { 
    if (z$x[i] == "a") 
    z$y[i] <- factor(z$y[i], levels = 1:2, labels = c("alpha", "beta")) 
    else 
    z$y[i] <- factor(z$y[i], levels = 1:2, labels = c("gamma", "delta")) 
} 

但它给了我好几个警告信息(为每个i)是这样的:

Warning messages: 
1: In `[<-.factor`(`*tmp*`, i, value = c(NA, 1L, 1L, 2L, 2L, 1L, 2L, : 
    invalid factor level, NAs generated 

然后,当我打电话z再次,数据帧乱七八糟,每y已被制作成<NA>

我敢打赌,这是一个简单的解决方案,但我一直在尝试小时几种方法无济于事。我的头即将爆炸!帮帮我!

+0

不能只需添加多种因素的新列级1:4和标签“阿尔法”,“测试版”,“伽马”,“三角洲”?它没有任何意义(我怀疑是可能的)有两个级别,但有4个标签的因素... – digEmAll 2012-02-20 20:37:07

+0

我可以在一个小数据集上做到这一点,比如上面的一个,但我的实际问题有几千行,该方法不切实际。 – 2012-02-20 20:52:20

+0

看看我的回答 – digEmAll 2012-02-20 21:17:05

回答

1
> z$ynew <- ifelse(z$x == "a", ifelse(z$y==1, "alpha", "beta"), 
           ifelse(z$y==1, "delta", "gamma")) 
> z 
    x y ynew 
1 a 1 alpha 
2 a 1 alpha 
3 a 1 alpha 
4 a 2 beta 
5 b 2 gamma 
6 b 1 delta 
7 b 2 gamma 
8 b 2 gamma 

(我猜我换你的三角洲和伽玛的。如果你想“ynew”是一个因素则刚:?z$ynew <- factor(z$ynew)

+0

这个字,但我的实际'y'矢量有八个级别,所以'ifelse()'不起作用。除非我把八个ifelses嵌入另一个,这对我来说太过分了。这个案件有没有任何扫描? – 2012-02-20 20:50:36

+0

可能...提供更现实的问题描述和示例。 – 2012-02-20 21:08:26

1

有关使用合并什么

# define x and y to 'alpha', 'beta' etc. correspondences 
# (it's just one row for each possible factor) 
auxDf <- data.frame(x = c('a',  'a', 'b',  'b' ), 
        y = c(1,  2,  1,  2 ), 
        newy= c('alpha', 'beta', 'gamma', 'delta')) 

# merge the 2 data.frame getting a new data.frame with the factors column 
newDf <- merge(z,auxDf) 
newDf 
+0

感谢您的输入,但这需要重新创建所有向量,对不对?一个人如何在一个大数据集上做这项工作? – 2012-02-21 19:14:32

+0

@wleoncio:同时创建2个子集,每个前面的data.frame的大1/2,创建相同数量的变量:)你有内存问题吗? – digEmAll 2012-02-21 20:06:27

1

这里有一个额外的步骤使以前的答案更快 - 您可以使用'unique'来抽出数据帧中的所有唯一组合。

auxDf=unique(z) 
auxDf$newy=c('alpha','beta','gamma','delta') 

然后,在以前的帖子

newDf <- merge(z,auxDf) 
newDf 
+0

欢迎来到堆栈溢出,珍妮!请考虑编辑digEmAll的答案并在那里插入额外的步骤;这样,我们可以将所有相关步骤放在一起。 SO的答案是动态排序的,所以参考“以前的答案”可能不会每次都有效。 ;) – 2012-02-21 15:19:47

0

我已经成功地拿出这样的作品,即使它是相当混乱的解决方案。

首先,对于每个x

z1 <- subset(z, x == "a") 
z2 <- subset(z, x == "b") 

创建数据帧z的子集然后,应用factor()到每个子集:

z1$y <- factor(z1$y, levels = 1:2, labels = c("alpha", "beta")) 
z2$y <- factor(z2$y, levels = 1:2, labels = c("gamma", "delta")) 

最后,团聚子集成原始对象。

z <- rbind(z1, z2) 
+0

我不明白你为什么喜欢@DWin解决方案或其他人提出的方法;他们给出了基本上相同的结果,并且在许多条件下(例如'a','b','c'...),您需要执行很多子集... – digEmAll 2012-02-21 18:09:24

+0

你是对的,这个只是解决问题的另一种方法。只是使用子集的工作对于我来说看起来不像嵌套ifelses。现在,我更喜欢这个或者是DWin的解决方案,因为它们处理导入的数据框(你的建议涉及重新创建每个变量,对吧?)。 – 2012-02-21 19:13:31