2013-01-24 12 views
10

Buna koşmaya devam ediyorum ve kolay bir iş olup olmadığını merak ediyorum. (Bir tamsayı matrisiyle bir data.frame alt kümesinin oluşturulması

> dat[sel.mat] 
[1] 0.2582569 0.8455966 0.8828083 0.5384263 0.9574810 0.5623158 
> dat[sel.mat] <- NA 
Error in `[<-.data.frame`(`*tmp*`, sel.mat, value = NA) : 
    only logical matrix subscripts are allowed in replacement 

ben hata iletisi için bir neden yok olduğunu fark: Bazı durumlar için ben daha mantıklı

N <- 12 
N.NA <- 6 
dat <- data.frame(V1=runif(N),V2=runif(N)) 
sel.mat <- matrix(c(sample(seq(N),N.NA),sample(ncol(dat),N.NA,replace=TRUE)),ncol=2) 

Bu, seçim için çalışır bir matris subsetting düşünmek ancak değiştirme için bulmak Aynı öğeye işaret eden birden çok değiştirmenin olması durumunda ne yapacağınızı bilmezsiniz, ancak bu R'nin vektörler üzerinde tamsayı değiştirmeye izin vermesini engeller (örn. dat$V1[c(2,3)] <- NA).

Tamsayı matrisi ile değiştirmeye izin vermenin uygun bir yolu var mı?

+1

, 'dat [sel.mat] <- NA' ** ** desteklenir. Matriks indekslemesi, R-3.0.0'dan itibaren mevcut olacaktır. (Daha fazla bilgi için aşağıdaki cevaba bakın.) –

cevap

2

FWIW, cari R-devel anlık çalışır değiştirme ile matris indeksleme (ve irade R-3.0.0'un bir parçası olun). Belli ki, R-çekirdekli biri seninle aynı dileği vardı. R-devel NEWS file kanıtlandığı gibi

: dataframes arasında

Matris indeksleme iki sütunlu sayısal endekslerle şimdi değiştirme olarak çıkarılması için desteklenir.

bir gösteri: Mevcut R devel bir anlık olarak

dat[sel.mat] 
## [1] 0.3355509 0.4114056 0.2334332 0.6597042 0.7707762 0.7783584 
dat[sel.mat] <- NA 
dat[sel.mat] 
## [1] NA NA NA NA NA NA 

R.version.string 
# [1] "R Under development (unstable) (2012-12-29 r61478)" 
+0

Zaman, tüm sorunları gerçekten çözer. –

+0

Evet. Kodu Ekim 2012'de geri eklediler ve bu sayı Nisan 2013'e kadar numaralandırılmış bir sürüm haline gelmeyecek, ancak bence iyi beta testi her zaman böyle görünüyor! –

0

Belki bir döngü kullanıyor?

for (i in 1:nrow(sel.mat)) 
{ 
    dat[sel.mat[i,1],sel.mat[i,2]] <- NA 
} 

> dat 
       V1   V2 
    1   NA 0.27002155 
    2 0.7253383   NA 
    3   NA 0.63847293 
    4 0.1768720 0.64586587 
    5 0.3796935 0.62261843 
    6 0.6751365 0.78328647 
    7 0.9801140 0.82259732 
    8   NA 0.08606641 
    9 0.3294625 0.44110121 
    10 0.2830957   NA 
    11 0.6868594 0.09767882 
    12 0.9802349   NA 
7

bir matris bunu dönüştürme:

: Biz data.frame

dat.m[sel.mat] <- NA 

ile bir hata var neden

dat.m <- as.matrix(dat) 
dat.m[sel.mat] <- NA 
> dat.m 
      V1   V2 
[1,] 0.2539189   NA 
[2,] 0.5216975   NA 
[3,] 0.1206138 0.14714848 
[4,] 0.2841779 0.52352209 
[5,] 0.3965337   NA 
[6,] 0.1871074 0.23747235 
[7,] 0.2991774   NA 
[8,]  NA 0.09509202 
[9,] 0.4636460 0.59384430 
[10,] 0.5493738 0.92334630 
[11,] 0.7160894   NA 
[12,] 0.9568567 0.80398264 

Düzenleme açıklamak aşağıdakileri yapın eşdeğerdir

temp <- dat 
dat <- "[<-"(temp, sel.mat, value=NA) 

Error in `[<-.data.frame`(temp, sel.mat, value = NA) : 
only logical matrix subscripts are allowed in replacement 

şimdi follwing yapabilirsiniz ve çalışır:

dat <- "[<-"(as.matrix(temp), sel.mat, value=NA) 
6

Sen tamsayı matrisine dayalı bir mantıksal matrisi oluşturabilirsiniz:

Bu matris ile veri çerçevesindeki değerlerini değiştirmek için kullanılabilecek
log.mat <- matrix(FALSE, nrow(dat), ncol(dat)) 
log.mat[sel.mat] <- TRUE 

NA (ya da başka değerler):

is.na(dat) <- log.mat 

sonucu:

  V1   V2 
1 0.76063534   NA 
2 0.27713051 0.10593451 
3 0.74301263 0.77689458 
4 0.42202155   NA 
5 0.54563816 0.10233017 
6   NA 0.05818723 
7 0.83531963 0.93805113 
8 0.99316128 0.61505393 
9 0.08743757   NA 
10 0.95510231 0.51267338 
11 0.14035257   NA 
12 0.59408022   NA 

Bu, özgün nesneyi farklı türlerdeki sütunlara izin veren veri çerçevesi olarak tutmanıza olanak tanır. R ise

2

, ifadeler

dat[sel.mat] 
dat[sel.mat] <- NA 

S3 yöntem ve class(dat) "data.frame" olduğu

`[.data.frame`(x=dat, i=sel.mat) 
`[<-.data.frame`(x=dat, i=sel.mat, value=NA) 

eşdeğerdir.

Sen

`[.data.farme` 
`[<-.data.frame` 

kaynak koduna bakmak ve ne istediğinizi onu değiştirebilir.

`[<-.data.frame` <- function(x, i, j, value) { 
    if (class(i) != "matrix") return(base:::`[<-.data.frame`(x, i, j, value)) 
    if (class(i[1]) != "integer") return(base:::`[<-.data.frame`(x, i, j, value)) 
    # check the length of i and value here 
    if (length(value) < nrow(i)) { 
    if (nrow(i) %% length(value) != 0) warning("some warning message should be here") 
    value <- rep(value, nrow(i) %/% length(value) + 1) 
    } 
    value <- value[1:nrow(i)] 
    for(index in 1:nrow(i)) { 
    x[i[index,1], i[index,2]] <- value[index] 
    } 
    return(x) 
} 

denemek: Senin durumunda


, belki istediğiniz

N <- 12 
N.NA <- 6 
dat <- data.frame(V1=runif(N),V2=runif(N)) 
sel.mat <- matrix(c(sample(seq(N),N.NA),sample(ncol(dat),N.NA,replace=TRUE)),ncol=2) 
dat[sel.mat] <- NA 
dat 
+0

(+1) de. Bunun neden bu temel fonksiyonların yeniden yazılmasından daha fazla upvot almadığına emin değilsiniz, karışıklıktan kaçınmak için genellikle en iyi şekilde kaçınılır. Ama bu güzel bir açıklama. –

İlgili konular