2014-09-18 19 views
5

Tôi cần đặt một số giá trị số trong một cột của khung dữ liệu thành 0, nếu ở cột khác, chúng có một mức yếu tố nhất định.Thay đổi giá trị số trong một cột dựa trên các mức hệ số trong cột khác

dataframe df của tôi trông giống như sau:

Items Store.Type 
5  A 
4  B 
3  C 
6  D 
3  B 
7  E 

Những gì tôi muốn làm là làm cho mục = 0, cho tất cả các hàng nơi Store.Type = "A" hoặc "C"

tôi m rất mới để R, nhưng figured này này sẽ là một tuyên bố có điều kiện của mẫu "Nếu Store.Type A sau đó Items < - 0" (và sau đó lặp lại cho Store.Type C), nhưng tôi đã không hiểu các trang ?"if" ở tất cả. Tôi cố gắng:

df$ItemsFIXED <- with(df, if(Store.Type == "A")Items <-0) 

và nhận được tin nhắn cảnh báo:

Warning message: 
In if (Store.Type2 == "Chain - Brand") Total.generic.items <- 0 : 
the condition has length > 1 and only the first element will be used` 

Vì vậy, tôi để ý thấy here, như sau:

  • if is a control flow statement, taking a single logical value as an argument
  • ifelse is a vectorised function, taking vectors as all its arguments.

Vì vậy, tìm tôi cần ifelse để làm toàn bộ cột và là có thể hiểu được trang ?ifelse, tôi đã cố gắng làm "Nếu Store.Type A thì Items < - 0 người khác không làm gì". Trong thực tế, tôi muốn nó lồng nhau, vì vậy tôi cố gắng đoạn mã sau (tạo một cột mới cho bây giờ vì vậy tôi không gây rối lưu dữ liệu của tôi, nhưng cuối cùng nó sẽ ghi đè lên dữ liệu Items)

df$ItemsFIXED <- with(df, ifelse(Store.Type == "A", Items <-0, 
          ifelse(Store.Type == "C", Items <-0,))) 

và nhận được những điều sau đây lỗi:

Error in ifelse(Store.Type2 == "Franchise - Brand", Total.generic.items <- 0, : 
    argument "no" is missing, with no default 

Nhưng nếu tôi đặt bất cứ điều gì trong cho no nó chỉ đơn giản viết trên các giá trị đó là chính xác. Tôi đã thử đặt ItemsItems <- Items để nói "khác để lại Mục dưới dạng mục" như sau, nhưng điều này chỉ thay đổi mọi thứ thành 0.

df$ItemsFIXED <- with(df, ifelse(Store.Type == "A", Items <-0, 
          ifelse(Store.Type == "C", Items <-0,Items))) 

Có cách nào để yêu cầu ifelse không làm gì hoặc có cách nào dễ dàng hơn để thực hiện việc này không?

+1

'df $ Các mục [trong đó (df $ Store.Type == "A" | df $ Store.Type == "C")] <- 0' – Alex

+0

tức là tìm các hàng cần được thay đổi, sau đó đặt các mục đó thành 0. – Alex

+0

Cảm ơn tất cả mọi người vì những giải pháp đó, chúng thực sự đều hoạt động, nhưng tôi không chắc chắn làm thế nào/tại sao! Tôi nghĩ rằng 'which' và'% in% 'dường như là những cái đơn giản nhất mà tôi nên xem xét nhiều hơn. – JenLouise

Trả lời

5

Hoặc bạn có thể sử dụng %in% cho nhiều trận đấu/thay thế

df$Items[df$Store.Type %in% c("A", "C")] <- 0 
    df 
    #Items Store.Type 
    #1  0   A 
    #2  4   B 
    #3  0   C 
    #4  6   D 
    #5  3   B 
    #6  7   E 
1

Bạn có thể sử dụng thay thế được vector hóa tại đây. Nếu df là bộ dữ liệu của bạn,

> df$Items[with(df, Store.Type == "A" | Store.Type == "C")] <- 0L 
> df 
# Items Store.Type 
# 1  0   A 
# 2  4   B 
# 3  0   C 
# 4  6   D 
# 5  3   B 
# 6  7   E 

with(df, Store.Type == "A" | Store.Type == "C") trả về một vector logic. Khi một vectơ logic được đặt bên trong [...], chỉ trả lại giá trị TRUE. Vì vậy, nếu chúng ta tập hợp con Items với những giá trị đó, chúng ta có thể thay thế chúng với [<-

Ngoài ra, nếu bạn muốn sử dụng ifelse, bạn có thể làm những việc như

df$Items <- with(df, ifelse(Store.Type == "A" | Store.Type == "C", 0L, Items)) 

hoặc

within(df, Items <- ifelse(Store.Type == "A" | Store.Type == "C", 0L, Items)) 

nhưng mất lưu ý rằng ifelse có thể rất chậm ở lần, thậm chí nhiều hơn như vậy khi kết hợp với within và có thể sẽ luôn chậm hơn phương pháp vectơ lên ​​trên cùng.

1

Tiếp theo cũng làm việc:

> ddf[ddf$Store.Type=='A'| ddf$Store.Type=='C',]$Items = 0 
> ddf 
    Items Store.Type 
1  0   A 
2  4   B 
3  0   C 
4  6   D 
5  3   B 
6  7   E 
2

Sử dụng within có vẻ là cũng là một lựa chọn:

within(d, Items[Store.Type %in% c("A","C")]<-0) 

    Items Store.Type 
1  0   A 
2  4   B 
3  0   C 
4  6   D 
5  3   B 
6  7   E 
+0

+1 Có vẻ tốt, chưa bao giờ thử trước đây. – akrun

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