在R中,将数据帧中的向量值分割为多列

时间:2017-02-22 19:39:21

标签: 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

是2x2数据帧,第二列是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的{​​{1}}之类的东西?

4 个答案:

答案 0 :(得分: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适用于vectorlist列,但结果是长格式的 - 您必须添加列ID并将其展开以将其恢复广泛的形式。

但是,最简单的方法可能是将dplyrsummarize_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 :(得分:1)

是。使用dplyr相对容易。

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

答案 2 :(得分:1)

一个基本R替代方案是使用aggregatetapply的内部函数,并使用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)

答案 3 :(得分: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