R转置数字data.frame导致字符变量

R transposing numeric data.frame results in character variables

我有一个 data.frame,其中包含一个字符变量和多个数字变量,如下所示:

sampleDF <- data.frame(a = c(1,2,3,"String"), b = c(1,2,3,4), c= c(5,6,7,8), stringsAsFactors = FALSE)

看起来像这样:

       a b c
1      1 1 5
2      2 2 6
3      3 3 7
4 String 4 8

我想转置这个 data.frame 并让它看起来像这样:

  V1 V2 V3     V4
1  1  2  3 String
2  1  2  3      4
3  5  6  7      8

我试过了

c<-t(sampleDF)

以及

d<-transpose(sampleDF)

但这两种方法都会导致 V1、V2 和 V3 现在是字符类型,尽管只有数值。

我知道这个问题已经被问过多次了。但是,对于为什么在这种情况下 V1、V2 和 V3 也被转换为字符,我还没有找到合适的答案。

有什么方法可以确保这些列保持数字?

非常感谢任何已经为这个问题的重复性质道歉的人。

编辑:

as.data.frame(t(sampleDF)

没有解决问题:

'data.frame':   3 obs. of  4 variables:
 $ V1: Factor w/ 2 levels "1","5": 1 1 2
  ..- attr(*, "names")= chr  "a" "b" "c"
 $ V2: Factor w/ 2 levels "2","6": 1 1 2
  ..- attr(*, "names")= chr  "a" "b" "c"
 $ V3: Factor w/ 2 levels "3","7": 1 1 2
  ..- attr(*, "names")= chr  "a" "b" "c"
 $ V4: Factor w/ 3 levels "4","8","String": 3 1 2
  ..- attr(*, "names")= chr  "a" "b" "c"

转置后,将列转换为 numerictype.convert

out <- as.data.frame(t(sampleDF), stringsAsFactors = FALSE)
out[] <- lapply(out, type.convert, as.is = TRUE)
row.names(out) <- NULL
out
#   V1 V2 V3     V4
#1  1  2  3 String
#2  1  2  3      4
#3  5  6  7      8

str(out)
#'data.frame':  3 obs. of  4 variables: 
#  $ V1: int  1 1 5
#  $ V2: int  2 2 6
#  $ V3: int  3 3 7    
#  $ V4: chr  "String" "4" "8"

rbind将第一列转换为相应的'types'并转置其他列

rbind(lapply(sampleDF[,1], type.convert, as.is = TRUE), 
               as.data.frame(t(sampleDF[2:3])))

注意:第一种方法效率更高


或者另一种方法是 paste 将每列中的值放在一起,然后再次阅读

read.table(text=paste(sapply(sampleDF, paste, collapse=" "), 
     collapse="\n"), header = FALSE, stringsAsFactors = FALSE)
#  V1 V2 V3     V4
#1  1  2  3 String
#2  1  2  3      4
#3  5  6  7      8

或者我们可以将 'data.frame' 转换为 'data.matrix',这会将 character 元素更改为 NA,使用 is.na 查找元素的索引用于替换原始字符串值的 NA

m1 <- data.matrix(sampleDF)
out <- as.data.frame(t(m1))
out[is.na(out)] <- sampleDF[is.na(m1)]

或者另一个选项是 type_convert 来自 readr

library(dplyr)
library(readr)
sampleDF %>% 
     t %>%
     as_data_frame %>%
     type_convert
# A tibble: 3 x 4
#     V1    V2    V3 V4    
#   <int> <int> <int> <chr> 
#1     1     2     3 String
#2     1     2     3 4     
#3     5     6     7 8