2017-03-20 9 views
0

この質問には多くのものがあります。まず、データを列cで分割したいと思います。部分集合は因子cによって与えられ、レベルは1〜4である。したがって、4つの異なるセグメント。 次の2つの列があります。 a列とb列。 NAを各セグメント固有の列の最大値に置き換えたいと思います。たとえば、行3と列 'a'のNAは30になります。(b、3)は80、(b、8)は50、(a、5)は80になります。NAを行と列に固有の値に置き換えてください。

私は仕事をしている下のコードを作成しましたが、今はすべてのセグメントと列に対してforループのように自動化する必要があります。どうすればこのことができますか?

a <- c(10,NA,30,40,NA,60,70,80,90,90,80,90,10,40) 
b <- c(80,70,NA,50,40,30,20,NA,0,0,10,69, 40, 90) 
c <- c(1,1,1,2,2,2,2,2,3,3,3,4,4,4) 


     a b c 
1: 10 80 1 
2: NA 70 1 
3: 30 NA 1 
4: 40 50 2 
5: NA 40 2 
6: 60 30 2 
7: 70 20 2 
8: 80 NA 2 
9: 90 0 3 
10: 90 0 3 
11: 80 10 3 
12: 90 69 4 
13: 10 40 4 
14: 40 90 4 


mytable <- data.table(a,b,c) 

mytable[which(is.na(mytable[c == 1][,1, with = FALSE]) == TRUE),1] <- max(mytable[c==1,1], na.rm = TRUE) 

残念ながら、これはエラーに結果を試してみてください:[<-.data.table

for(i in unique(mytable$c)){ 
    for(j in unique(c(1:2))){ 
    mytable[which(is.na(mytable[c == i][,j, with = FALSE]) == TRUE),j, with = FALSE] <- max(mytable[c==i][,j, with = FALSE], na.rm = TRUE) 
    } 
} 

エラー(*tmp*、(is.na([、J = FALSE付き] [C == i]はmytableは)==: = FALSEと未使用の引数()

驚くべきことに、これは、同様にエラーになる:

for(i in unique(mytable$c)){ 
    for(j in unique(c(1:2))){ 
    mytable[which(is.na(mytable[c == i][,j]) == TRUE),j] <- max(mytable[c==i,j], na.rm = TRUE) 
    } 
} 

[.data.table(mytable、c == i、j)のエラー: j([...]内の2番目の引数)は単一のシンボルですが、列名 'j'が見つかりません。おそらくあなたはDT [、.. j]またはDT [、j、= FALSE]を意図していました。このdata.frameとの違いは、意図的なものであり、FAQ 1.1で説明されています。

+0

の使用: a)、b = ifelse(is.na(a)、max(a、na.rm = TRUE)、a = ifelse(is.na(a)、max(a、na.rm = TRUE) ' – count

答えて

4
library("data.table") 

mytable <- data.table(
a=c(10,NA,30,40,NA,60,70,80,90,90,80,90,10,40), 
b=c(80,70,NA,50,40,30,20,NA,0,0,10,69, 40, 90), 
c=c(1,1,1,2,2,2,2,2,3,3,3,4,4,4)) 

foo <- function(x) { x[is.na(x)] <- max(x, na.rm=TRUE); x } 

mytable[, .(A=foo(a), B=foo(b)), by=c] 

> mytable[, .(A=foo(a), B=foo(b)), by=c] 
# c A B 
# 1: 1 10 80 
# 2: 1 30 70 
# 3: 1 30 80 
# 4: 2 40 50 
# 5: 2 80 40 
# 6: 2 60 30 
# 7: 2 70 20 
# 8: 2 80 50 
# 9: 3 90 0 
#10: 3 90 0 
#11: 3 80 10 
#12: 4 90 69 
#13: 4 10 40 
#14: 4 40 90 

またはabの直接の置換のため:

mytable[, `:=`(a=foo(a), b=foo(b)), by=c] # or 
mytable[, c("a", "b") := (lapply(.SD, foo)), by = c] # from @Sotos 

または安全変異体(TNXが発言用@Frankする):

cols <- c("a", "b") 
mytable[, (cols) := lapply(.SD, foo), by=c, .SDcols=cols] 
+1

または 'dt [、lapply(.SD、foo)、by = c]' – Sotos

+0

これは 'mを変更しません。 ytable'と置き換えられた値のみを出力します – manotheshark

+0

@manotheshark私は自分の答えを編集しました。 – jogo

0

パッケージplyrから利用ddply()

結果
df<-data.frame(a,b,c=as.factor(c)) 
library(plyr) 
df2<-ddply(df, .(c), transform, a=ifelse(is.na(a), max(a, na.rm=T),a), 
      b=ifelse(is.na(b), max(b, na.rm=T),b)) 
2

`dplyr`を使用data.table

library(data.table) 
mytable[, a := ifelse(is.na(a), max(a, na.rm = TRUE), a), by = c] 
mytable[, b := ifelse(is.na(b), max(b, na.rm = TRUE), b), by = c] 

または単一のコマンドで

mytable[, c("a", "b") := lapply(.SD, function(x) ifelse(is.na(x), max(x, na.rm = TRUE), x)), .SDcols = c("a", "b"), by = c] 
関連する問題