为什么在R中使用转置函数会将数字转换为字符?

16

我在Excel中创建了一个简单的矩阵,其中包含一些字符值和一些数字值(在Excel中设置数据的屏幕截图)。我使用openxlsx软件包将其读入R中,如下所示:

library(openxlsx)
data <- read.xlsx('~desktop/data.xlsx)

接下来我检查这个类:

sapply(data, class)
         x1         a         b          c
"character" "numeric" "numeric"  "numeric"

这正是我想要的。但当我尝试对矩阵进行转置并再次检查类时,出现了问题:

data <- t(data)

现在我用sapply检查时,所有的值都是"character"。为什么在转置时没有保留类别?


4
如果出现混合类型,matrix 只能接受单一的字符类。如果您指定您真正想要的内容,那么可能会有比转置更好的选项。 - akrun
3
检查 'data' 的 str。它应该是 data.frame - akrun
我真正想要的是:我有一个类似于data.xlsx示例的xlsx文件,但它大约有100k行和100列。我将其读入R并选择可能用于进一步处理的10行。最终,我希望能够将这10行写入新的xlsx文件,但为了可读性,我想要转置矩阵。 - Morten Nielsen
谢谢,这很有道理,包装运行得很好,只是像你说的,所有东西都被转换成了因子。我认为仅转置数值列对我来说行不通,因为我不想失去“字符”和“数值”之间的关系。 - Morten Nielsen
1
谢谢。问题在于我有两列包含字符值需要保留。 - Morten Nielsen
显示剩余5条评论
1个回答

12

首先,当我在您的电子表格中读取逗号分隔的数字时,由于这些单元格显示为字符,因此我无法获得您的结果。

data <- read.xlsx("data.xlsx")
data
#  X1   a b   c
#1  x 0,1 3 4,5
#2  y 2,4 0 6,5
#3  z  24 0   0
sapply(data,class)
#         X1           a           b           c 
#"character" "character"   "numeric" "character" 

然而,你实际上看到的问题是,在转置数据框时,你正在将不同类型的数据混合在同一列中,因此 R 必须将整个列转换为最宽泛的通用类型,本例中为字符类型。

mydata<-data.frame(X1=c("x","y","z"),a=c(1,2,24),b=c(3,0,0),c=c(4,6,0),stringsAsFactors = FALSE)
sapply(mydata,class)
#         X1           a           b           c 
#"character"   "numeric"   "numeric"   "numeric" 
# what you showed
t(mydata)
#   [,1] [,2] [,3]
#X1 "x"  "y"  "z" 
#a  " 1" " 2" "24"
#b  "3"  "0"  "0" 
#c  "4"  "6"  "0" 

mydata_t<-t(mydata)
sapply(mydata_t,class)
#          x           1           3           4           y           2           #0           6           z          24 
#"character" "character" "character" "character" "character" "character" #"character" "character" "character" "character" 
#          0           0 
#"character" "character" 

你是否想在转置矩阵中处理数字并在处理后再次进行转置?如果是这样,可以暂时删除包含字符列的子矩阵,然后再重新组合,具体步骤如下:

sub_matrix<-t(mydata[,-1])
sub_matrix
#  [,1] [,2] [,3]
#a    1    2   24
#b    3    0    0
#c    4    6    0
sub_matrix2<-sub_matrix*2
sub_matrix2
#  [,1] [,2] [,3]
#a    2    4   48
#b    6    0    0
#c    8   12    0
cbind(X1=mydata[,1],as.data.frame(t(sub_matrix2)))
#  X1  a b  c
#1  x  2 6  8
#2  y  4 0 12
#3  z 48 0  0

1
非常感谢。我使用的是丹麦机器,这就是为什么逗号分隔的数字会被读取为数字的原因。您的解决方案似乎几乎是我正在寻找的,除了我不想将其转置回来。我基本上需要对其进行转置,然后找到一种方法将字符列(未包含在子矩阵中,参见您的示例)添加为新转换矩阵的第一行。最终,整个包括字符列的矩阵应该被转置。也许我可以创建两个不同的子矩阵,单独对它们进行转置,然后重新组合它们rbind? - Morten Nielsen
“矩阵”必须全部为同一类型。数据框可以混合列类型,但不能混合行类型。你可以使用rownames()和names()分别设置行名和列名。很抱歉我没有注意到欧洲小数点的约定。 - Art
我成功地通过@Art的答案以稍微不同的方式解决了我的问题,我相信这个答案将帮助其他遇到类似问题的人,所以我会在它上面打一个勾。 - Morten Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接