2012-02-20 56 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