2017-02-22 3 views
1

У меня есть dataframe, где один столбец является матрицей, а не вектором, и я хотел бы разбить его на несколько столбцов с векторным значением.В R, разбитый вектор значащий столбец в кадре данных на несколько столбцов

Например, это

set.seed(101) 
Df <- data.frame(x = runif(100), 
       y = round(runif(100))) 

descriptives <- function(arg) c(mean(arg), median(arg), sd(arg)) 
results <- aggregate(x ~ y, data=Df, descriptives) 

дает мне

> results 
    y  x.1  x.2  x.3 
1 0 0.4710224 0.4280053 0.3206661 
2 1 0.5769064 0.6220120 0.2683387 

который является 2х2 dataframe со второго столбца, являющегося 2x3 матрица:

> dim(results) 
[1] 2 2 
> results[,2] 
      [,1]  [,2]  [,3] 
[1,] 0.4710224 0.4280053 0.3206661 
[2,] 0.5769064 0.6220120 0.2683387 

Я хотел бы разбить эту матрицу на три столбца.

я мог бы сделать

results <- cbind(results$y, as.data.frame(results[,2])) 
names(results) <- c('y', 'mean', 'median', 'sd') 

> results 
    y  mean median  sd 
1 0 0.4710224 0.4280053 0.3206661 
2 1 0.5769064 0.6220120 0.2683387 

Но есть более прямой и менее Hacky способ? Я думаю о чем-то вроде tidyr's separate?

+0

может быть что-то вроде 'as.data.frame (матрицы (unlist (результаты), nrow = nrow (результаты)))'? – Sotos

ответ

1

В этом случае, с матрицей, вы можете использовать cbind:

cbind(results[1], results[[2]]) 
# y   1   2   3 
# 1 0 0.4710224 0.4280053 0.3206661 
# 2 1 0.5769064 0.6220120 0.2683387 

Использование [ на первый аргумент делает, что он является data.frame, так cbind.data.frame используется, и результат не принуждают к матрице. Но используя [[ по второму аргументу, убедитесь, что мы привязываемся к матрице 2x3 во втором столбце, а не к кадру данных, содержащему эту матрицу.

В целом, tidyr::unnest хорошо работает с vector или list колонн, но результат в длинной форме - вы бы добавить столбец идентификатор и распространить его, чтобы получить его обратно в широкую форму.

Однако самый простой способ может быть использование dplyr и summarize_at с настраиваемыми .funs аргументом:

library(dplyr) 
descrip = funs(m = mean, med = median, sd = sd) 
Df %>% group_by(y) %>% summarize_at("x", .funs = descrip) 
# # A tibble: 2 × 4 
#  y   m  med  sd 
# <dbl>  <dbl>  <dbl>  <dbl> 
# 1  0 0.4710224 0.4280053 0.3206661 
# 2  1 0.5769064 0.6220120 0.2683387 
1

Да. Это относительно просто с dplyr.

library(dplyr) 
results <- Df %>% group_by(y) %>% 
     summarize(mean = mean(x), 
        median = median(x), 
        sd = sd(x)) 
1

Одна базовой R альтернативой является использованием внутренней функцией aggregate, tapply и использовать lapply пробежать каждый статистический расчет:

# collect desired statistical calculations in a named list 
descriptives <- list(mean=mean, median=median, sd=sd) 

# get data.frame of values 
dfStats <- data.frame(lapply(descriptives, function(f) tapply(Df$x, Df$y, f))) 
dfStats 
     mean median  sd 
0 0.4710224 0.4280053 0.3206661 
1 0.5769064 0.6220120 0.2683387 

Здесь lapply пробегает список функций и применяется tapply, чтобы получить групповые вычисления. Полученный список помещается в data.frame с data.frame. Обратите внимание, что y - это row.names, но вы можете легко вытащить это из row.names.

dfStats$y <- row.names(dfStats) 
1

Один из подходов к затруднительное проблема (хотя, как уже отмечалось, из, проблема может быть избежать) заключается в использовании do.call(data.frame, ...).

Пример:

do.call(data.frame, results) 
# y  x.1  x.2  x.3 
# 1 0 0.4710224 0.4280053 0.3206661 
# 2 1 0.5769064 0.6220120 0.2683387 
str(.Last.value) 
# 'data.frame': 2 obs. of 4 variables: 
# $ y : num 0 1 
# $ x.1: num 0.471 0.577 
# $ x.2: num 0.428 0.622 
# $ x.3: num 0.321 0.268 
Смежные вопросы