2016-05-05 1 views
0

у меня есть dataframe («DF») двух переменных х и у:dcast затем конкатенации преобразованных переменных

a <- c(1:2000) 
b <- c(1:4000) 
c <- 5000 

df <- data.frame(x = sample(a, c, replace = TRUE), 
       y = as.character(sample(b, c, replace = TRUE))) 
df <- df[order(df$x), ] 

head(df, 10) 
    x y 
881 1 2919 
4425 1 2000 
2478 2 3375 
4808 2 3928 
4871 2 3351 
4889 2 1634 
1242 3 3957 
1378 3 3356 
3029 3 2625 
3657 4 646 

То, что я хотел бы сделать сейчас уменьшить dataframe содержать только отдельные переменные х (например, один «1», один «2», один «3» и т. д.) и имеют новое поле, которое объединяет разные значения x в y, разделенные запятыми. Конечный результат будет выглядеть следующим образом:

head(df3) 
    x    multi_ys 
1 1    2000, 2919 
2 2 1634, 3351, 3375, 3928 
3 3  2625, 3356, 3957 
4 4    1092, 646 
5 5 113, 2430, 3187, 932 
6 7     2349 

У меня есть решение прямо сейчас, что работает, но я думаю, что это более громоздким, чем это необходимо. Мое решение текущего состояния ниже, и для «df» dataframe из 5000 строк для создания «df3» требуется около 12 секунд.

library(reshape2) 

#creates a duplicate field of y, to dcast in the 'multi_y' function below 
df$y2 <- df$y 

#creates a new dataframe with unique x values 
df2 <- df[which(!duplicated(df$x)), ] 


multi_y <- function(x) { 
    c3.i <- df2[x, 1] 
    c3.j <- df[df$x == c3.i, ] 
    c3.k <- dcast(c3.j, x ~ y, value.var = "y2") 
    cols <- colnames(c3.k) 

    #if there are more than two columns in this loop's data frame, then concatenate all columns except the first 
    if(ncol(c3.k) > 2) { 
    c3.k$cycles <- apply(c3.k[ , cols[-1]] , 1 , paste , collapse = ", ") 
    } else { 
    c3.k$cycles <- c3.k[, 2] 
    } 

    c3.l <- cbind(data.frame(c3.k[, 1]), data.frame(c3.k[, ncol(c3.k)])) 
    colnames(c3.l) <- c("x", "multi_ys") 
    print(c3.l) 
} 

t <- (1:nrow(df2)) 
system.time(df3 <- do.call("rbind", lapply(t, function(x) multi_y(x)))) 

Мой фактический dataframe составляет более 80 000 строк, и я должен запустить этот тип функции 4 разное время в моей программе.

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

+1

Вы можете попробовать 'библиотека (dplyr); df%>% group_by (x)%>% summary (y = toString (y)) ' –

ответ

2

Как насчет

df1 <- aggregate(y~x, df, paste, collapse = ',') 
head(df1) 
# x         y 
#1 1         542 
#2 2      3813,1220,1666 
#3 3 1713,35,643,3957,872,2235,3015,3051 
#4 4      2037,1371,1180 
#5 5       2724,905 
#6 6       293,3248