2015-09-14 19 views
14

Tôi muốn thay thế các NA có trong cột của DATA TABLE bằng giá trị trung bình của cùng một cột. Tôi đang làm như sau. Nhưng nó không hoạt động.Thay thế các NA bằng giá trị trung bình của cùng một cột dữ liệu. Có thể

ww <- data.table(iris) 

ww <- ww[1:5 , ] 

ww[1,1] <- NA 

    Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
1:   NA   3.5   1.4   0.2 setosa 
2:   4.9   3.0   1.4   0.2 setosa 
3:   4.7   3.2   1.3   0.2 setosa 
4:   4.6   3.1   1.5   0.2 setosa 
5:   5.0   3.6   1.4   0.2 setosa 


ww[is.na(Sepal.Length) , Sepal.Length:= mean(Sepal.Length, na.rm = T)] 

    Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
1:   NaN   3.5   1.4   0.2 setosa 
2:   4.9   3.0   1.4   0.2 setosa 
3:   4.7   3.2   1.3   0.2 setosa 
4:   4.6   3.1   1.5   0.2 setosa 
5:   5.0   3.6   1.4   0.2 setosa 

Tại sao tôi nhận NaN thay cho NA khi giá trị trung bình của các giá trị còn lại (4.9, 4.7, 4.6, 5.0)?

Thay thế của việc đạt được điều này trong trường hợp có điều gì sai với cú pháp này?

Tôi muốn cú pháp cho bảng dữ liệu.

+2

Vấn đề là bạn đang Subsetting dataset đầu tiên, sau đó áp dụng một hoạt động để các 'Sepal.Length' cột, trong đó chỉ chứa một 'NA' duy nhất tại thời điểm này. –

+0

@AkhilNair không giúp bạn. Bạn có thể vui lòng đưa ra một ví dụ? – user3664020

+0

@RHertel giải pháp của bạn đang thay thế toàn bộ cột không chỉ NA. – user3664020

Trả lời

21

na.aggregate trong gói vườn thú thay thế NAS với giá trị trung bình của phi NA trong cùng một cột:

library(zoo) 

ww[, Sepal.Length := na.aggregate(Sepal.Length)] 
+0

Tôi không chắc chắn na.aggregate vẫn là một chức năng trong data.table ... – colin

+1

'na.aggregate' là một chức năng trong sở thú. Lưu ý câu lệnh 'library'. –

+0

Cảm ơn rất nhiều. Trước khi tôi tạo một bài đăng mới, có cách nào để lập chỉ mục giải pháp sao cho trung bình các cột không phải NA có một số nhóm khác, chẳng hạn như loài? – colin

4

Nó không lấy giá trị trung bình của toàn bộ cột Sepal.Length; chỉ có 1 cột mà bạn đã chọn.

Thay sử dụng:

ww[is.na(Sepal.Length) , Sepal.Length:= mean(ww$Sepal.Length, na.rm=TRUE)] 
+0

là cú pháp này hợp lệ cho data.table? – user3664020

+0

@ user3664020 hiện tại. – zx8754

+3

Đây có lẽ là thực tế không tốt để gọi 'Sepal.Length' trong phạm vi' ww' từ phạm vi toàn cục. Với một ví dụ khác, bạn có thể đã sắp xếp lại các cột sẽ sửa đổi các thứ tiếp theo nếu bạn gọi 'ww' trên toàn cầu. –

6

Trong cơ sở R:

ww$Sepal.Length[is.na(ww$Sepal.Length)] <- mean(ww$Sepal.Length, na.rm = T) 
+4

bạn có thể chuyển đổi cú pháp này thành cú pháp của data.table không? – user3664020

6

nỗ lực của bạn subsetted bảng đầu tiên, chọn

> ww[is.na(Sepal.Length)] 
    Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
1: 

    NA   3.5   1.4   0.2 setosa 

vì vậy bất kỳ hoạt động hơn nữa chỉ có thể 'nhìn thấy' những hàng - tức là Sepal.Length chỉ có thể thấy một số NA.

Giải pháp data.table bạn muốn bên dưới - nó xem toàn bộ bảng và thay thế NA s bằng các phương tiện sử dụng ifelse.

ww[, Sepal.Length := ifelse(is.na(Sepal.Length), mean(Sepal.Length, na.rm = TRUE), Sepal.Length)] 
+2

Hoặc 'ww [, Sepal.Length: = thay thế (Sepal.Length, is.na (Sepal.Length), trung bình (Sepal.Length, na.rm = TRUE))]' vì 'ifelse' thường chậm. Làm phiền rằng 'Sepal.Length' cần phải được gõ bốn lần ở đây. – Frank

8

Trong khi câu trả lời zoo là khá tốt đẹp nó đòi hỏi phụ thuộc mới.
Chỉ sử dụng data.table bạn có thể làm như sau.

library(data.table) 

# prepare data 
ww = data.table(iris[1:5,]) 
ww[1, Sepal.Length := NA] 

# solution 
ww[, Sepal.Length.mean := mean(Sepal.Length, na.rm = TRUE) # calculate mean 
    ][is.na(Sepal.Length), Sepal.Length := Sepal.Length.mean # replace NA with mean 
    ][, Sepal.Length.mean := NULL # remove mean col 
     ][] # just prints 

Trong khi nó có vẻ hơi to so với sở thú, nó là hoạt động hiệu quả như tất cả các bước được thực hiện sử dụng cập nhật bằng cách tham khảo:=. Nó cũng có thể dễ dàng điều chỉnh để thay thế NA bằng giá trị trung bình theo nhóm, chỉ cần sử dụng đối số by trong data.table.

3

tidyr đã tích hợp sẵn chức năng, replace_na bạn có thể sử dụng cho việc này:

library(tidyr) 
ww %>% replace_na(list(Sepal.Length = mean(.$Sepal.Length, na.rm = TRUE))) 
Các vấn đề liên quan