2014-04-30 14 views
25

Tôi có một bảng có hai cột: cho dù bạn bị bệnh (H01) và số ngày bị bệnh (H03). Tuy nhiên, số ngày ốm là NA nếu H01 == false, và tôi muốn đặt nó là 0. Khi tôi làm điều này:Khi cố gắng thay thế giá trị, "giá trị bị thiếu không được phép trong phân đoạn chỉ số của khung dữ liệu"

test <- pe94.person[pe94.person$H01 == 12,] 
test$H03 <- 0 

Nó hoạt động tốt. Tuy nhiên, tôi muốn thay thế các giá trị trong dataframe ban đầu. Này, tuy nhiên, thất bại:

pe94.person[pe94.person$H01 == 12,]$H03 <- 0 

Nó trả về:

> pe94.person[pe94.person$H01 == 12,]$H03 <- 0 
Error in `[<-.data.frame`(`*tmp*`, pe94.person$H01 == 12, , value = list(: 
    missing values are not allowed in subscripted assignments of data frames 

Bất cứ ý tưởng tại sao điều này là gì? Đối với những gì nó có giá trị, đây là một bảng tần số:

> table(pe94.person[pe94.person$H01 == 12,]$H03) 

2 3 5 28 
3 1 1 1 
+4

M ost có khả năng vì bạn có 'NA' trong cột 'H01'. Lưu ý đối số 'useNA' vào bảng mà bạn chưa sử dụng. Ngoài ra, nó có thể tốt hơn (theo phong cách) để tham khảo cột bên trong '[' thay vì sử dụng '$'. – joran

+0

Điều đó có ý nghĩa; Tôi đã tìm được nhiều. Làm thế nào tôi có thể thay thế các Quốc hội? Xin lỗi, tôi không có nhiều kinh nghiệm với R. –

+1

'pe94.person $ H01 [is.na (p94.person $ H01)] <- value' có thể. – joran

Trả lời

6

Bạn có thể sử dụng ifelse, như vậy

pe94.person$foo <- ifelse(!is.na(pe94.person$H01) & pe94.person$H01 == 12, 0, pe94.person$H03) 

kiểm tra nếu foo đáp ứng tiêu chí của bạn và sau đó đi trước và gán nó vào pe94.person$H03 trực tiếp. Tôi thấy nó an toàn hơn để gán cho nó một biến mới và thường sử dụng nó trong phân tích tiếp theo.

26

Đó là do sự thiếu trong biến số H01.

> x <- data.frame(a=c(NA,2:5), b=c(1:5)) 
> x 
    a b 
1 NA 1 
2 2 2 
3 3 3 
4 4 4 
5 5 5 
> x[x$a==2,]$b <- 99 
Error in `[<-.data.frame`(`*tmp*`, x$a == 1, , value = list(a = NA_integer_, : 
    missing values are not allowed in subscripted assignments of data frames 

Bài tập sẽ không hoạt động vì x$a có giá trị bị thiếu.

Subsetting tác phẩm đầu tiên:

> z <- x[x$a==2,] 
> z$b <- 99 
> z <- x[x$a==2,] 
> z 
    a b 
NA NA NA 
2 2 2 

Nhưng đó là bởi vì các [<- chức năng dường như không thể xử lý thiếu giá trị trong chỉ số khai thác của nó, mặc dù [ có thể:

> `[<-`(x,x$a==2,,99) 
Error in `[<-.data.frame`(x, x$a == 2, , 99) : 
    missing values are not allowed in subscripted assignments of data frames 

Vì vậy, thay vào đó, cố gắng xác định phần !is.na(x$a) của bạn khi bạn đang thực hiện nhiệm vụ:

> `[<-`(x,!is.na(x$a) & x$a==2,'b',99) 
    a b 
1 NA 1 
2 2 99 
3 3 3 
4 4 4 
5 5 5 

Hoặc, phổ biến hơn:

> x[!is.na(x$a) & x$a==2,]$b <- 99 
> x 
    a b 
1 NA 1 
2 2 99 
3 3 3 
4 4 4 
5 5 5 

Lưu ý rằng hành vi này được mô tả trong the documentation:

Các phương pháp thay thế có thể được sử dụng để thêm toàn bộ cột (s) bằng cách xác định cột không tồn tại (Trong đó, các cột được thêm vào ở cạnh bên phải của khung dữ liệu và các chỉ số bằng số phải tiếp giáp với các chỉ mục hiện có. Mặt khác, các hàng có thể được thêm vào ở bất kỳ hàng nào sau hàng cuối cùng hiện tại và các cột sẽ được lấp đầy bằng các giá trị bị thiếu. Giá trị thiếu trong các chỉ mục không được phép thay thế.

+0

Bạn cũng có thể nhận được các giá trị bị thiếu bằng cách sử dụng toán tử '% in%' thay vì '==', xem [ở đây] (https://stackoverflow.com/q/16822426/4241780) để được giải thích. Vì vậy, hoặc là 'x [x $ a% trong% 2,] $ b <- 99', hoặc cho ví dụ OP' pe94.person [pe94.person $ H01% trong% 12,] $ H03 <- 0', sẽ công việc. – JWilliman

2

Chỉ cần sử dụng chức năng subset() để loại trừ tất cả NA khỏi chuỗi.

Nó hoạt động như x[subset & !is.na(subset)].Nhìn vào số liệu này:

> x <- data.frame(a = c(T,F,T,F,NA,F,T, F, NA,NA,T,T,F), 
>     b = c(F,T,T,F,T, T,NA,NA,F, T, T,F,F)) 

Subsetting với [ điều hành trả về này:

> x[x$b == T & x$a == F, ] 

     a b 
2 FALSE TRUE 
NA  NA NA 
6 FALSE TRUE 
NA.1 NA NA 
NA.2 NA NA 

subset() làm những gì chúng ta muốn:

> subset(x, b == T & a == F) 

     a b 
2 FALSE TRUE 
6 FALSE TRUE 

Để thay đổi giá trị của biến subsetted:

> ss <- subset(x, b == T & a == F) 
> x[rownames(ss), 'a'] <- T 

> x[c(2,6), ] 

    a b 
2 TRUE TRUE 
6 TRUE TRUE 
Các vấn đề liên quan