2011-10-05 59 views
18

Tôi muốn tạo cột mới dựa trên 4 giá trị trong một cột khác.Tạo cột mới dựa trên 4 giá trị trong cột khác

if col1=1 then col2= G; 
if col1=2 then col2=H; 
if col1=3 then col2=J; 
if col1=4 then col2=K. 

LÀM THẾ NÀO ĐỂ LÀM VIỆC NÀY? Tôi cần ai đó giúp giải quyết vấn đề này. Tôi đã thử nếu/else và ifelse nhưng không ai có vẻ là làm việc. Cảm ơn

+0

bạn đang sử dụng ngôn ngữ lập trình nào? –

+2

@TheGiG OP đánh dấu câu hỏi bằng [tag: r] – Andrie

+0

Có liên quan cao: [trường hợp câu lệnh tương đương] (http://stackoverflow.com/q/4622060/168747), [Cách thêm cột vào một dữ liệu '. frame'?] (http://stackoverflow.com/q/4562547/168747), [Làm sạch dữ liệu trong trang tính Excel] (http://stackoverflow.com/q/7374314/168747) (trong tập hợp các liên kết khác này). – Marek

Trả lời

15

Bạn có trường hợp đặc biệt tra cứu các giá trị trong đó chỉ mục là số nguyên 1: 4. Điều này có nghĩa là bạn có thể sử dụng lập chỉ mục vectơ để giải quyết vấn đề của mình chỉ trong một bước dễ dàng.

Đầu tiên, tạo một số dữ liệu mẫu:

set.seed(1) 
dat <- data.frame(col1 = sample(1:4, 10, replace = TRUE)) 

Tiếp theo, xác định các giá trị tra cứu và sử dụng [ Subsetting để tìm ra kết quả mong muốn:

values <- c("G", "H", "J", "K") 
dat$col2 <- values[dat$col1] 

Kết quả:

dat 
    col1 col2 
1  2 H 
2  2 H 
3  3 J 
4  4 K 
5  1 G 
6  4 K 
7  4 K 
8  3 J 
9  3 J 
10 1 G 

Tổng quát hơn, bạn có thể sử dụng [ Subsetting kết hợp với match để giải quyết loại vấn đề:

index <- c(1, 2, 3, 4) 
values <- c("G", "H", "J", "K") 
dat$col2 <- values[match(dat$col1, index)] 
dat 
    col1 col2 
1  2 H 
2  2 H 
3  3 J 
4  4 K 
5  1 G 
6  4 K 
7  4 K 
8  3 J 
9  3 J 
10 1 G 
5

Có một số cách để thực hiện việc này, nhưng đây là một cách.

set.seed(357) 
mydf <- data.frame(col1 = sample(1:4, 10, replace = TRUE)) 
mydf$col2 <- rep(NA, nrow(mydf)) 
mydf[mydf$col1 == 1, ][, "col2"] <- "A" 
mydf[mydf$col1 == 2, ][, "col2"] <- "B" 
mydf[mydf$col1 == 3, ][, "col2"] <- "C" 
mydf[mydf$col1 == 4, ][, "col2"] <- "D" 

    col1 col2 
1  1 A 
2  1 A 
3  2 B 
4  1 A 
5  3 C 
6  2 B 
7  4 D 
8  3 C 
9  4 D 
10 4 D 

Đây là một trong số sử dụng car 's recode.

library(car) 
mydf$col3 <- recode(mydf$col1, "1 = 'A'; 2 = 'B'; 3 = 'C'; 4 = 'D'") 

Thêm một từ this question:

mydf$col4 <- c("A", "B", "C", "D")[mydf$col1] 
1

Bạn có thể có một cái nhìn tại ?symnum.

Trong trường hợp của bạn, một cái gì đó như:

col2<-symnum(col1, seq(0.5, 4.5, by=1), symbols=c("G", "H", "J", "K")) 

nên giúp bạn có được đóng lại.

21

Bạn có thể sử dụng lồng ifelse:

col2 <- ifelse(col1==1, "G", 
     ifelse(col1==2, "H", 
     ifelse(col1==3, "J", 
     ifelse(col1==4, "K", 
         NA )))) # all other values map to NA 

Trong trường hợp này đơn giản đó là quá mức cần thiết, nhưng đối với phức tạp hơn những người ...

+1

"nhưng đối với những người phức tạp hơn ..." - những người phức tạp hơn làm cho lồng nhau 'ifelse' a ** tốt hơn ** ý tưởng? Đó là phản trực giác đối với tôi. –

+0

@TheRedPea Đối với các điều kiện phức tạp hơn, dựa trên các cột khác nhau, không liên quan đến nhau, vv Một dòng cho một điều kiện. – Marek

+0

Vâng, tôi đoán người ta có thể không có lựa chọn nào khác ngoài việc thể hiện logic với câu lệnh if. –

Các vấn đề liên quan