定义其级别取决于另一个变量的因子

时间:2012-02-20 20:22:17

标签: r dataframe

是这个模拟数据:

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>

我打赌这有一个简单的解决方案,但我一直在尝试小时的几种方法无济于事。我的脑袋即将爆炸!救命啊!

4 个答案:

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

(我想我换掉了你的delta和gamma。如果你想'ynew'成为一个因素,那么:z$ynew <- factor(z$ynew)

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

答案 2 :(得分:1)

这是使前一个答案更快一点的额外步骤 - 您可以使用“unique”来提取数据框中的所有唯一组合。

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

然后,如上一篇文章

newDf <- merge(z,auxDf) 
newDf

答案 3 :(得分:0)

我设法提出了一个有效的解决方案,即使它非常混乱。

首先,为每个z

创建数据框x的子集
z1 <- subset(z, x == "a")
z2 <- subset(z, x == "b")

然后,将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)