2014-11-06 3 views
-1

У меня есть кадр данных, как это:значения падения переменных, если они соответствуют одному из других

Family Component x1 m_x1 x2 m_x2 x3 m_x3 y1 m_y1 y2 m_y2 y3 m_y3 
a1  1   1 100 2 300 0 0  2 250 0 0  0 0 
a1  2   1 100 2 300 0 0  2 250 0 0  0 01 
a1  3   1 100 2 300 0 0  2 250 0 0  0 0 
a2  1   2 150 0 0  0 0  0 0  0 0  0 0 
a2  2   2 150 0 0  0 0  0 0  0 0  0 0 
a3  1   1 4000 3 150 4 130 2 150 3 400 0 0 
a3  2   1 4000 3 150 4 130 2 150 3 400 0 0 
a3  3   1 4000 3 150 4 130 2 150 3 400 0 0 
a3  4   1 4000 3 150 4 130 2 150 3 400 0 0 

Семья является группировка переменной. Тогда я хочу, что если значение "Component" (для каждого Family) НЕ совпадают один в x1, x2, , y1, y2, y3, значение этой переменной, а следующий (для x1, m_x1, для x2, m_x2 , ...). В результате я бы хотел:

Family Component x1 m_x1 x2 m_x2 x3 m_x3 y1 m_y1 y2 m_y2 y3 m_y3 
a1  1   1 100 0 0  0 0  0 0  0 0  0 0 
a1  2   0 0  2 300 0 0  2 250 0 0  0 0 
a1  3   0 0  0 0  0 0  0 0  0 0  0 0 
a2  1   0 0  0 0  0 0  0 0  0 0  0 0 
a2  2   2 150 0 0  0 0  0 0  0 0  0 0 
a3  1   1 4000 0 0  0 0  0 0  0 0  0 0 
a3  2   0 0  0 0  0 0  2 150 0 0  0 0 
a3  3   0 0  3 150 0 0  0 0  3 400 0 0 
a3  4   0 0  0 0  4 130 0 0  0 0  0 0 

Какую функцию использовать? Я пробовал слияние, но не мог заставить его работать.

+0

Использование 'melt' на этом dataframe бы сделать этот процесс намного проще. –

+0

@akrun да, спасибо. –

ответ

2

Вот простой способ:

# find nonmatching entries 
idx <- dat[-(1:2)][c(TRUE, FALSE)] != dat$Component 

# full index 
idx_full <- idx[ , rep(seq(ncol(idx)), each = 2)] 

# replace values with 0 
dat[-(1:2)][idx_full] <- 0 

dat 
# Family Component x1 m_x1 x2 m_x2 x3 m_x3 y1 m_y1 y2 m_y2 y3 m_y3 
# 1  a1   1 1 100 0 0 0 0 0 0 0 0 0 0 
# 2  a1   2 0 0 2 300 0 0 2 250 0 0 0 0 
# 3  a1   3 0 0 0 0 0 0 0 0 0 0 0 0 
# 4  a2   1 0 0 0 0 0 0 0 0 0 0 0 0 
# 5  a2   2 2 150 0 0 0 0 0 0 0 0 0 0 
# 6  a3   1 1 4000 0 0 0 0 0 0 0 0 0 0 
# 7  a3   2 0 0 0 0 0 0 2 150 0 0 0 0 
# 8  a3   3 0 0 3 150 0 0 0 0 3 400 0 0 
# 9  a3   4 0 0 0 0 4 130 0 0 0 0 0 0 

где dat это имя вашего фрейма данных.

1

Вы можете попробовать:

cols <- as.vector(t(outer(c("x","y"), 1:3, 
        function(...) paste(...,sep="")))) 
df[, 3:ncol(df)] <- do.call(cbind, lapply(cols, function(x) df[, 
           c(x,paste(sep="","m_",x))]*(df[[x]]==df$Component))) 
1

Если столбцы всегда не в том же порядке, вы также можете сделать:

n1 <- unique(gsub(".+\\_", "", colnames(df1)[-(1:2)])) 

df1[,-(1:2)] <- do.call(cbind,lapply(n1, function(x) { 
         indx <- grep(x, names(df1)) 
         m1 <- as.matrix(df1[indx]) 
         m1[m1[,1]!=df1$Component] <- 0 
         as.data.frame(m1) })) 
    df1 
    # Family Component x1 m_x1 x2 m_x2 x3 m_x3 y1 m_y1 y2 m_y2 y3 m_y3 
    #1  a1   1 1 100 0 0 0 0 0 0 0 0 0 0 
    #2  a1   2 0 0 2 300 0 0 2 250 0 0 0 0 
    #3  a1   3 0 0 0 0 0 0 0 0 0 0 0 0 
    #4  a2   1 0 0 0 0 0 0 0 0 0 0 0 0 
    #5  a2   2 2 150 0 0 0 0 0 0 0 0 0 0 
    #6  a3   1 1 4000 0 0 0 0 0 0 0 0 0 0 
    #7  a3   2 0 0 0 0 0 0 2 150 0 0 0 0 
    #8  a3   3 0 0 3 150 0 0 0 0 3 400 0 0 
    #9  a3   4 0 0 0 0 4 130 0 0 0 0 0 0 
Смежные вопросы