2014-09-17 2 views
4

Это является продолжением этого вопроса: Duplicating observations of a dataframe, but also replacing specific variable values in RДублирование и изменение строк в dataframe зависит от наблюдений [R]

Я пытался писать в сжатой форме, насколько это возможно, в то время предоставляя всю необходимую информацию. В этом текущем примере, у меня есть ФР, который выглядит следующим образом:

df<-data.frame(alpha=c(1, "3, 4", "2, 4, 5", 2, 1, 3, "1, 2", "1, 2, 3"), 
      beta=c("2, 4", "3, 4", 1, 3, 3, "1, 4", "1, 2", "1, 2, 3"), 
      color=c("red", "yellow")) 


# alpha beta color 
#1  1 2, 4 red 
#2 3, 4 3, 4 yellow 
#3 2, 4, 5  1 red 
#4  2  3 yellow 
#5  1  3 red 
#6  3 1, 4 yellow 
#7 1, 2 1, 2 red 
#8 1, 2, 3 1, 2, 3 yellow 

Желаемая выход

Я хочу, чтобы закончить тем, что-то вроде этого (порядок строк не так важно для меня):

# alpha beta color value 
#1  1 2 red  1 
#2  1 4 red  1 
#3  3 4 yellow 0.5 
#4  2 1 red  1 
#5  4 1 red  1 
#6  5 1 red  1 
#7  2 3 yellow  1 
#8  1 3 red  1 
#9  3 1 yellow  1 
#10 3 4 yellow  1 
#11 1 2 red 0.5 
#12 1 2 yellow 0.5 
#13 1 3 yellow 0.5 
#14 2 3 yellow 0.5 

Всякий раз, когда есть наблюдение альфа или бета с множеством записей не перекрываются/несовпадающих, то, что наблюдение расширяется. например Строка 1 исходного df имеет альфа = «1» и бета = «2, 4». Они становятся двумя отдельными строками на выходе с разделенными «2» и «4» бета-версиями. Информация, содержащаяся в переменной «цвет», сохраняется для каждого наблюдения. Кроме того, новая переменная 'value' получает значение 1.

Ключевое различие между этим и предыдущим вопросом заключается в наличии строк, где alpha == beta.

Здесь я хочу только сохранить уникальные комбинации альфа и бета, а не дублировать. например строка 8 исходного df имеет альфа = «1, 2, 3» и бета = «1, 2, 3». Я хочу иметь отдельные строки, где «alpha = 1, beta = 2», «alpha = 1, beta = 3», «alpha = 2, beta = 3». Опять же, переменная цвета будет дублироваться. Однако здесь значение должно быть «0,5».

То, что я пробовал:

Я не мог понять, как сделать это все в одном, так что я первый подмножество ФР в зависимости от того альфа равен бета или нет.

x <- df[df$alpha!=df$beta,] 

df$alpha<-as.character(df$alpha) 
df$beta<-as.character(df$beta) 

fun1 <- function(df){ 
df$alpha<-as.character(df$alpha) 
df$beta<-as.character(df$beta) 

do.call(rbind, with(df, Map(expand.grid, 
          alpha = strsplit(alpha, ", "), 
          beta = strsplit(beta, ", "), 
          color = color, 
          value = 1 
))) 
} 

fun1(x) 

, который дает:

alpha beta color value 
#1  1 2 red  1 
#2  1 4 red  1 
#3  2 1 red  1 
#4  4 1 red  1 
#5  5 1 red  1 
#6  2 3 yellow  1 
#7  1 3 red  1 
#8  3 1 yellow  1 
#9  3 4 yellow  1 

Затем наблюдения, где альфа == бета, который является, где я застрял ...

x2 <- df[df$alpha==df$beta,] 
x2 

# alpha beta color 
#2 3, 4 3, 4 yellow 
#7 1, 2 1, 2 red 
#8 1, 2, 3 1, 2, 3 yellow 

Моя идея состояла в том, чтобы расколоть данных, используя strsplit, а затем использовать combn, чтобы найти комбинации, которые я ищу, и связывать их вместе. Однако, это не будет работать, как это, если я хочу, чтобы дублировать другие переменные ...

a<-strsplit(x2$alpha, ", ") 
a.combs <- lapply(a, function(x) c(combn(x, 2, simplify=FALSE))) 
matrix(unlist(a.combs),ncol=2, byrow=T) 

дает:

# [,1] [,2] 
#[1,] "3" "4" 
#[2,] "1" "2" 
#[3,] "1" "2" 
#[4,] "1" "3" 
#[5,] "2" "3" 

Любые идеи о том, как сделать получить эти комбинации вместе с пре- существующая переменная «цвет» и добавление новой переменной «значение».

ответ

4

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

Она начинается с довольно много той же точки, используя my cSplit function, вложенные в два раза, как это (но на этот раз, добавляя ID):

library(devtools) 
source_gist(11380733) 
temp <- cSplit(cSplit(cbind(id = 1:nrow(df), df), 
         "alpha", ",", "long"), 
       "beta", ",", "long") 

Вот новый материал:

SD <- c("alpha", "beta") 
## Convert "alpha" and "beta" to numeric 
temp[, (SD) := lapply(.SD, as.numeric), .SDcols = SD] 

## Sort your alphas and betas, and check for duplicates 
## and any points where alpha equals beta 
temp[, toDrop := duplicated(
    paste(pmin(alpha, beta), pmax(alpha, beta))) | 
    alpha == beta, by = id] 

## Create your "value" column 
temp[, value := ifelse(any(toDrop), 0.5, 1), by = id] 

## Subset and drop the irrelevant columns 
out <- temp[!temp[, toDrop, with = TRUE]][, toDrop := NULL] 

Это результат:

out 
#  id alpha beta color value 
# 1: 1  1 2 red 1.0 
# 2: 1  1 4 red 1.0 
# 3: 2  3 4 yellow 0.5 
# 4: 3  2 1 red 1.0 
# 5: 3  4 1 red 1.0 
# 6: 3  5 1 red 1.0 
# 7: 4  2 3 yellow 1.0 
# 8: 5  1 3 red 1.0 
# 9: 6  3 1 yellow 1.0 
# 10: 6  3 4 yellow 1.0 
# 11: 7  1 2 red 0.5 
# 12: 8  1 2 yellow 0.5 
# 13: 8  1 3 yellow 0.5 
# 14: 8  2 3 yellow 0.5 
+0

Вау, это здорово - спасибо. Это мотивирует меня узнать намного больше о data.table. Функция csplit является фантастической. Я тестировал его с различными образцами данных, и, похоже, он работает хорошо. Еще раз спасибо. – jalapic

+0

надеюсь, что вы увидите этот комментарий. Эта функция все еще отлично работает, когда я просто запускаю сценарий R. Однако, когда я помещаю его в пакет R, он не работает - возникают следующие ошибки ... 'Ошибка в': = '((SD), lapply (.SD, as.numeric)): Проверьте, что .data.table (DT) == TRUE. В противном случае: = и ': =' (...) определены для использования в j, как только и в частности способами. См. Help (": ="). 'Я полагаю, что это связано с обновлениями в' data.table'? но я не понимаю, почему это не сработает в моем пакете. Интересно, есть ли у вас идеи? Трудно сделать пример воспроизведения без всей информации о пакете. – jalapic

+0

@ jalapic, у вас есть репо где-то, как GitHub, и если да, возможно ли это увидеть? Существуют ли какие-либо строки в коде, которые переконвертируют 'data.table' в' data.frame', прежде чем перейти к шагу 'as.numeric'? – A5C1D2H2I1M1N2O1R2T1

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