从多个数据帧列到一个向量的值

时间:2013-12-12 05:51:33

标签: r dataframe

我有一个数据框df,其中包含很多cols并说100行。

如何从名称为“alpha”,“gamma”和“zeta”的列中获取所有级别值,并将其中的300个存储在一个向量中?

3 个答案:

答案 0 :(得分:11)

我发现首先转换为矩阵可以更容易地达到水平。

as.vector(as.matrix(df[,c("alpha", "gamma", "zeta")]))

当然,在最初读取数据时,您可能刚刚完成stringsAsFactors=FALSE

答案 1 :(得分:3)

您有一个已接受的答案,但这是我认为发生的事情:您有factorcharacter列的组合。在这种情况下,unlist不能直接使用,但如果它们都是factor,或者它们都是character,那么就没有问题:

一些示例数据:

mydf <- data.frame(A = LETTERS[1:3], B = LETTERS[4:6], C = LETTERS[7:9],
                   D = LETTERS[10:12], E = LETTERS[13:15])
df <- mydf
df$E <- as.character(df$E)
colsOfInterest <- c("A", "B", "E")

案例1,所有列都是因子

unlist(mydf[colsOfInterest], use.names = FALSE)
# [1] A B C D E F M N O
# Levels: A B C D E F M N O

案例2,E列=字符,其他栏因素

unlist(df[colsOfInterest], use.names = FALSE)
# [1] "1" "2" "3" "1" "2" "3" "M" "N" "O"

unlist(lapply(df[colsOfInterest], as.character), use.names = FALSE)
# [1] "A" "B" "C" "D" "E" "F" "M" "N" "O"

对于此处描述的规模的问题,基准测试显示,如果您不关心保留因素,首先转换为字符并使用unlist实际上是最快的方法。请注意,如果某些列是因子而某些列是字符,则fun1()的结果将不正确。这是100行data.frame的基准:

library(microbenchmark)    
microbenchmark(fun1(), fun2(), fun3())
# Unit: microseconds
#    expr      min        lq    median       uq      max neval
#  fun1()  572.606  587.3595  595.4845  606.175 3439.055   100
#  fun2()  327.570  334.6265  341.2550  350.449 3443.758   100
#  fun3() 1037.020 1055.6215 1064.1745 1086.197 3929.981   100

当然,这里我们谈的是微秒,但结果也是如此。

供参考,这是用于基准测试的内容。如果您要测试不同大小的nRow提取不同数量的列,请更改“nCol”和“data.frame”。

nRow <- 100
nCol <- 30
set.seed(1)
mydf <- data.frame(matrix(sample(LETTERS, nRow*nCol, replace = TRUE), nrow = nRow))
colsOfInterest <- sample(nCol, sample(nCol*.7, 1))
length(colsOfInterest)
# [1] 17

library(microbenchmark)    
fun1 <- function() unlist(mydf[colsOfInterest], use.names = FALSE)
fun2 <- function() unlist(lapply(mydf[colsOfInterest], as.character), use.names = FALSE)
fun3 <- function() as.vector(as.matrix(mydf[colsOfInterest]))
microbenchmark(fun1(), fun2(), fun3())

答案 2 :(得分:0)

 vec <- unlist(lapply( df[ , 
                        names(df) %in% c("alpha","gamma", "zeta") ],
                levels) )[1:300]

这将给出独特的水平。如果您想要这些列中的前300个值,请执行以下操作:

 vec <- unlist(lapply( df[ , 
                        names(df) %in% c("alpha","gamma", "zeta") ],
                as.character) )[1:300]