2016-02-19 10 views
6

.SDcols'un by gruplandırma değişkeni ile değişmesine izin veriliyor mu? Her yıl için farklı sütunlara .SDcols değiştirmek istediğim aşağıdaki durum var. .SDcols için değerler bir data.table içinde iken, bu değerleri kullanarak başka bir tabloda .SD işlevini çalıştırmaya çalışıyorum.İzin ver. SDcols, data değişkeninde grup değişkenine göre değişebilir

ben bariz bir yaklaşım eksik ve bu yanlış yapıyor, ama bu (değerler güncellenirken O sadece basit aradığınız geliyor bana

## Contains the .SDcols applicable to each year 
dat1 <- data.table(
    year = 1:4, 
    vals = lapply(1:4, function(i) letters[1:i]) 
) 

## Make the sample data (with NAs) 
set.seed(1775) 
dat2 <- data.table(year = sample(1:4, 10, TRUE)) 
dat2[, letters[1:4] := replicate(4, sample(c(NA, 1:5), 10, TRUE), simplify=FALSE)] 

## Goal: Sum up the columns in the corresponding .SDcols for each year 
## Attempt, doesn't work -- I think b/c .SDcols must be fixed? 
dat2[, SUM := rowSums(.SD, na.rm=TRUE), by=year, 
    .SDcols=unlist(dat1[year == .BY[[1]], vals])] 

## Desired result, by simply iterating through each possible year 
for (i in 1:4) { 
    dat2[year==i, SUM := rowSums(.SD, na.rm=TRUE), 
    .SDcols=unlist(dat1[year == i, vals])] 
} 

dat2[] 
#  year a b c d SUM 
# 1: 1 3 1 5 1 3 
# 2: 2 1 3 3 1 4 
# 3: 1 5 4 3 NA 5 
# 4: 4 1 NA 4 5 10 
# 5: 2 2 2 2 NA 4 
# 6: 2 NA 3 3 NA 3 
# 7: 4 2 3 2 NA 7 
# 8: 1 2 NA 5 4 2 
# 9: 2 3 3 5 1 6 
# 10: 3 NA 4 2 NA 6 

cevap

6

katılmak çalışıyordu ne am Oldukça büyük olasılıkla her bir değere göre dat1 (by = .EACHI). Her iki şekilde de, bu çözüm ve girişimi (matris dönüştürme nedeniyle) şişenin boynu rowSums olduğunu. Ben olsaydım, ben tüm NA s sıfıra dönüştürmek ve çalıştırmak için Reduce(`+`,...) yerine (orijinal verilerinizdeki değerleri değiştirmek isterseniz de emin değilim)

Yerinde olsam 210
dat2[dat1, 
     SUM := rowSums(.SD[, unlist(i.vals), with = FALSE], na.rm = TRUE), 
     on = "year", 
    by = .EACHI] 
dat2 
#  year a b c d SUM 
# 1: 1 3 1 5 1 3 
# 2: 2 1 3 3 1 4 
# 3: 1 5 4 3 NA 5 
# 4: 4 1 NA 4 5 10 
# 5: 2 2 2 2 NA 4 
# 6: 2 NA 3 3 NA 3 
# 7: 4 2 3 2 NA 7 
# 8: 1 2 NA 5 4 2 
# 9: 2 3 3 5 1 6 
# 10: 3 NA 4 2 NA 6 

olsa belirtildiği gibi, ben sıfıra NA s dönüştürmek istiyorum ve Reduce yerine

for(j in 2:ncol(dat2)) set(dat2, i = which(is.na(dat2[[j]])), j = j, value = 0L) 
dat2[dat1, 
     SUM := Reduce(`+`, .SD[, unlist(i.vals), with = FALSE]), 
     on = "year", 
    by = .EACHI] 
dat2 
#  year a b c d SUM 
# 1: 1 3 1 5 1 3 
# 2: 2 1 3 3 1 4 
# 3: 1 5 4 3 0 5 
# 4: 4 1 0 4 5 10 
# 5: 2 2 2 2 0 4 
# 6: 2 0 3 3 0 3 
# 7: 4 2 3 2 0 7 
# 8: 1 2 0 5 4 2 
# 9: 2 3 3 5 1 6 
# 10: 3 0 4 2 0 6 
+0

'listelenmemesini (i.vals) kullanmak' Beni şaşkına buydu . Bunun bir “.EACHI” problemi olduğundan emindim. +1 – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto 'i.' olmadan da çalışırdı, her zaman sadece güvenlik için kullanırım (diğer veri kümesinde de benzer bir sütun varsa), ya da sadece by = 'e atıfta bulunuyordunuz. EACHI kısmı? –