2016-06-09 25 views
8

Đây là mẫu dữ liệu của tôi từ CSV. Nó chứa ~ 10 cột.Thay NA bằng lần xuất hiện trước

Product_id Product_Weight Product_Name Shop_Name ... 
[1] A    10    xxxx   Walmart 
[2] B    12    yyyy   Target 
[3] C    11    zzzz   Target 
[4] A    NA    xxxx   Walmart 
[5] C    NA    zzzz   Target 

Tôi muốn điền NA vào hàng 4 và 5 tương ứng 10 và 11 (vì trọng lượng sản phẩm của A và C đã được biết từ hàng 1 và 3). Tôi muốn khung dữ liệu cuối cùng giống như thế này

Product_id Product_Weight Product_Name Shop_Name ... 
[1] A    10    xxxx   Walmart 
[2] B    12    yyyy   Target 
[3] C    11    zzzz   Target 
[4] A    10    xxxx   Walmart 
[5] C    11    zzzz   Target 

Cách tốt nhất để làm điều này trong R là gì?

+0

Các trọng số này luôn được đặt sao cho kết hợp Product_id - Product_name sẽ trả về cùng một trọng số? – lmo

+0

@lmo Đúng vậy. – Avis

+0

Một Giải Đáp khác về việc thay thế NA: http://stackoverflow.com/questions/32694313/handle-continous-missing-values-in-time-series-data – Jaap

Trả lời

5

Một tùy chọn khác với dplyrtidyr:

library(dplyr); library(tidyr); 
df %>% group_by(Product_id) %>% fill(Product_Weight) 

Source: local data frame [5 x 4] 
Groups: Product_id [3] 

    Product_id Product_Weight Product_Name Shop_Name 
     (fctr)   (int)  (fctr) (fctr) 
1   A    10   xxxx Walmart 
2   A    10   xxxx Walmart 
3   B    12   yyyy Target 
4   C    11   zzzz Target 
5   C    11   zzzz Target 

Kết quả được sắp xếp theo Product_id.

+0

cant dplyr làm điều này mà không cần sắp xếp lại? – rawr

9

Mặc dù là câu hỏi cho "xuất hiện trước" này sẽ có những bất lợi mà nếu là người đầu tiên Product_Weight trong bất kỳ Product_id được NA thì nó có thể không được điền thậm chí nếu chúng ta biết Product_Weight từ sau Product_id nên thay vì sử dụng lần xuất hiện trước đó, chúng tôi lấy giá trị trung bình của tất cả các quốc gia không phải là NA có cùng số Product_id. Vì tất cả những điều này nên cùng ý nghĩa của chúng là giá trị chung của chúng.

Nếu bạn thực sự làm muốn xảy ra trước đó sử dụng chức năng Prev nơi:

Prev <- function(x) na.locf(x, na.rm = FALSE) 

ở vị trí của na.aggregate trong (1) và (3) và không sử dụng (2).

Các giải pháp sau đây có những lợi thế mà họ tất cả:

  • giữ gìn trật tự của các đầu vào

  • làm việc ngay cả khi Product_Weight đầu tiên trong bất kỳ Product_id là NA

  • không sửa đổi đầu vào

Giải pháp đầu tiên có lợi thế bổ sung là chỉ có một dòng mã (cộng với câu lệnh library) và giải pháp thứ hai có lợi thế bổ sung là không sử dụng bất kỳ gói nào.

1) vườn thú :: na.aggregate Chúng tôi sử dụng na.aggregate trong gói vườn thú (mà thay thế tất cả NAS với mức trung bình của phi NAS) và chúng tôi áp dụng nó vào Product_Weight riêng cho từng Product_id.

library(zoo) 
transform(DF, Product_Weight = ave(Product_Weight, Product_id, FUN = na.aggregate)) 

cho:

Product_id Product_Weight Product_Name Shop_Name 
1   A    10   xxxx Walmart 
2   B    12   yyyy Target 
3   C    11   zzzz Target 
4   A    10   xxxx Walmart 
5   C    11   zzzz Target 

2) Không có gói Cách khác sử dụng Mean ở vị trí của na.aggregate nơi Mean được định nghĩa là:

Mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE)) 

3) dplyr/thú Add số hàng, nhóm theo số Product_id, điền vào NA như trong các giải pháp trước khi sử dụng hoặc na.aggregate như hình dưới đây hoặc Mean, sắp xếp lại thứ tự ban đầu và loại bỏ những con số hàng:

library(dplyr) 
library(zoo) 

DF %>% 
    mutate(row = row_number()) %>% 
    group_by(Product_id) %>% 
    mutate(Product_Weight = na.aggregate(Product_Weight)) %>% 
    ungroup() %>% 
    arrange(row) %>% 
    select(-row) 

Lưu ý: này đã được sử dụng cho đầu vào DF:

Lines <- " Product_id Product_Weight Product_Name Shop_Name 
    A    10    xxxx   Walmart 
    B    12    yyyy   Target 
    C    11    zzzz   Target 
    A    NA    xxxx   Walmart 
    C    NA    zzzz   Target" 
DF <- read.table(text = Lines, header = TRUE) 
2

Đây là giải pháp với các lệnh cơ sở R:

# create lookup table with item and weight combinations 
lookup<-unique(df[complete.cases(df[ ,1:2]),]) 

#  find the NAs needing replacement: which(is.na(df$weight)) 
#  find index in lookup tabe:match(df$a[which(is.na(df$weight)) 
#  subset: df$weight[which(is.na(df$weight)) 
df$weight[which(is.na(df$weight))]<-lookup$weight[match(df$Product_id[which(is.na(df$weight))], lookup$Product_id)] 

Nhiều khả năng không hiệu quả như giải pháp dplyr/tidyr nêu trên.

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