2015-11-09 4 views
1

Я пытаюсь организовать набор данных очень определенным образом для своих исследований, однако я новичок в R, и я действительно борется, любая помощь будет очень признательна.с использованием crossprod при определенных условиях

Я пытаюсь принять значение ячейки в каждом третьем столбце (начиная с первого) и умножить его на столбец рядом с ним, но только если в указанной ячейке есть отрицательное значение. После этого я хотел бы суммировать результаты и сохранить их в новом столбце во внешней электронной таблице.

до сих пор код, который я написал следующим образом:

NegTotal = NULL 
    p = NULL 
    for (i in 1:nrow(Datafile)) 
     {for (j in 1:ncol(Datafile)) 
      {if ((j %% 3 == 0) && (Datafile [i,j] < 0)) { 
       p <- (datafile[i,j] * datafile[i,j+1]) 
       NegTotal <- sum(p) } 
      else { } 
      } 
     } 
    for (l in seq(along = NegTotal)) { 
     dim(newColumn) 
     AsNewData.DataColumn("datafile", GetType(System.String)) 
     NewColumn.DefaultValue = "NegTotal" 
     table.Columns.Add(newColumn) 
    } 

Я знаю, что этот код, вероятно, совершенно неправильно, это первый раз, когда я использовал R, и я не очень опытный в компьютерное программирование в целом.

В настоящее время данные организованы следующим образом:

df <- data.frame(F1 = c(1, -2, -1), E1 = c(1, 1, 0), Y1 = c(0, 0, 1), 
       F2 = c(-1, 2, -1), E2 = c(1, 1, 1), Y2 = c(0, 0, 1), 
       F3 = c(-2, -2, -1), E3 = c(1, 1, 1), Y3 = c(1, 1, 0)) 

# F1 E1 Y1 F2 E2 Y2 F3 E3 Y3 
# 1 1 1 0 -1 1 0 -2 1 1 
# 2 -2 1 0 2 1 0 -2 1 1 
# 3 -1 0 1 -1 1 1 -1 1 0 

Желаемый выход:

# F1 E1 Y1 F2 E2 Y2 F3 E3 Y3 NegTotal 
# 1 1 1 0 -1 1 0 -2 1 1  -3 
# 2 -2 1 0 2 1 0 -2 1 1  -4 
# 3 -1 0 1 -1 1 1 -1 1 0  -2 

Таким образом, если х = Fy * Еу; NegTotal = x1 + x2 + x3, только когда F $ y < 0.

Надеюсь, что все имеет смысл!

+0

Можете ли вы разместить образец своих данных и отобразить желаемый результат? Также проверьте: [Как сделать отличный воспроизводимый пример] (http://stackoverflow.com/q/5963269/2572423) – JasonAizkalns

+0

@JasonAizkalns Обратите внимание на отредактированный пост. – CrmC

ответ

0

Этот код даст вам желаемый результат. Однако, если ваш фактический набор данных более сложный, чем пример, который вы дали, вам может потребоваться более элегантное решение.

df$NegTotal<- (pmin(0,df$F1) * df$E1) + (pmin(0,df$F2) * df$E2) + (pmin(0,df$F3) * df$E3) 
+0

К сожалению, набор данных большой (2147 x 117), так что это не сработает. Спасибо хоть! @ Pash101 – CrmC

+0

Не беспокойтесь, существуют ли названия стиля «Fx», «Ex», «Yx» в вашем фактическом наборе? – Pash101

+0

Да, к сожалению, я знаю, что это усложняет ситуацию. Я пытаюсь организовать данные из вопросника, поэтому «F» «E» и «Y» представляют разные типы данных для каждого вопроса, заданного участниками. Следующие числа представляют собой номер вопроса. @ Pash101 – CrmC

1

Вот как я бы подойти к этому с dplyr и tidyr:

library(dplyr) 
library(tidyr) 

# Add a respondent column (i.e. row number) 
df$respondent <- 1:nrow(df) 

df %>% 
    gather(key, value, -respondent) %>% 
    separate(key, c("letter", "letter_sub"), sep = 1) %>% 
    spread(letter, value) %>% 
    mutate(Neg = ifelse(F < 0, E * F, NA)) %>% 
    group_by(respondent) %>% 
    summarise(NegTotal = sum(Neg, na.rm = TRUE)) 

# Source: local data frame [3 x 2] 
# 
# respondent NegTotal 
#  (int) (dbl) 
# 1   1  -3 
# 2   2  -4 
# 3   3  -2 

Чтобы понять, что происходит, я бы запустить конвейер по частям. Например, посмотрите на результаты первых нескольких функций:

df %>% 
    gather(key, value, -respondent) %>% 
    separate(key, c("letter", "letter_sub"), sep = 1) %>% 
    spread(letter, value) 

# respondent letter_sub E F Y 
# 1   1   1 1 1 0 
# 2   1   2 1 -1 0 
# 3   1   3 1 -2 1 
# 4   2   1 1 -2 0 
# 5   2   2 1 2 0 
# 6   2   3 1 -2 1 
# 7   3   1 0 -1 1 
# 8   3   2 1 -1 1 
# 9   3   3 1 -1 0 

Получение данных в таком виде, делает его легче выполнять суммарные задачи.

Смежные вопросы