2

apply 和 R 3.0.1 有一个奇怪的问题。

我有一个包含文本、数字和逻辑值的巨大数据框。当我使用 apply 时,逻辑值被转换为 chr,但是因为 R 允许类似 TRUE == "TRUE" 的东西,这不是问题。

但是对于某些逻辑值,apply 似乎在前面加上一个空格,并且 TRUE == "TRUE" 返回 NA。当然,我可以

sapply(cuelist[,4],FUN=function(logicalvalue) as.logical(sub("^ +", "", logicalvalue)))

但这并不好,我仍然不知道为什么 R 会这样做。

df <- data.frame(test=c("a","b","<",">"),logi=c(TRUE,FALSE,FALSE,TRUE))
apply(df, MARGIN=1, function(listelement) print(listelement) )

有趣的是,空格仅出现在本例中的 [2,1] 和 [2,4]

version _
platform x86_64-w64-mingw32
arch x86_64
os mingw32
system x86_64, mingw32
status
major 3
minor 0.1
year 2013
month 05
day 16
svn rev 62743
language R
version.string R version 3.0.1 (2013-05-16) 昵称 Good Sport

编辑:R 版本 2.15.0 (2012-03-30) 上的相同行为

Edit2:我的数据框像这样

> df
  test  logi
1    a FALSE
2    b FALSE
3    <  TRUE
4    >  TRUE

> str(df)
'data.frame':   4 obs. of  2 variables:
 $ test: Factor w/ 4 levels "<",">","a","b": 3 4 1 2
 $ logi: logi  FALSE FALSE TRUE TRUE
4

2 回答 2

3

在某种程度上,问题在于apply,但更恰当地说,问题在于as.matrix,以及它如何处理logical值。

以下是一些示例,可帮助详细说明我对 Karl 的查询。

首先,让我们创建四个data.frames 来做一些测试。

  1. 您的原始data.frame演示行为:
  2. Adata.frame在“测试”列中包含不同数量的字符,以查看 Karl 对正在发生的事情的解释。
  3. Adata.frame有一些数字可以帮助我们开始了解实际发生的情况。
  4. data.frame明确创建“logi”列的位置as.character
df1 <- data.frame(test = c("a","b","<",">"),
                  logi = c(TRUE,FALSE,FALSE,TRUE))
df2 <- data.frame(test = c("aa","b","<",">>"), 
                  logi = c(TRUE,FALSE,FALSE,TRUE))
df3 <- data.frame(test = c("aa","b","<",">>"), 
                  logi = c(TRUE,FALSE,FALSE,TRUE),
                  num = c(1, 12, 123, 2))
df4 <- data.frame(test = c("aa","b","<",">>"), 
                  logi = as.character(c(TRUE,FALSE,FALSE,TRUE)))

现在,让我们使用它们中的as.matrix每一个。

这之前有一个空格TRUE

as.matrix(df1)
#      test logi   
# [1,] "a"  " TRUE"
# [2,] "b"  "FALSE"
# [3,] "<"  "FALSE"
# [4,] ">"  " TRUE"

这之前有一个空格TRUE,但“测试”列不受影响。唔。

as.matrix(df2)
#      test logi   
# [1,] "aa" " TRUE"
# [2,] "b"  "FALSE"
# [3,] "<"  "FALSE"
# [4,] ">>" " TRUE"

啊...这在较短的数字之前有一个空格TRUE 和空格。因此,似乎 R 正在考虑 and 的数字基础值TRUE,但计算andFALSE中字符数的宽度。同样,第一个“测试”列不受影响。TRUEFALSE

as.matrix(df3)
#      test logi    num  
# [1,] "aa" " TRUE" "  1"
# [2,] "b"  "FALSE" " 12"
# [3,] "<"  "FALSE" "123"
# [4,] ">>" " TRUE" "  2"

如果您告诉 R 该logi列是字符列,那么这里的情况似乎很好。

as.matrix(df4)
#      test logi   
# [1,] "aa" "TRUE" 
# [2,] "b"  "FALSE"
# [3,] "<"  "FALSE"
# [4,] ">>" "TRUE" 

对于它的价值,sapply似乎没有这个问题。

sapply(df1, as.matrix)
#      test logi   
# [1,] "a"  "TRUE" 
# [2,] "b"  "FALSE"
# [3,] "<"  "FALSE"
# [4,] ">"  "TRUE" 

更新

在 R 公共聊天室中,Joshua Ulrich 指出自己format是罪魁祸首。as.matrix用于as.vector因子,将它们转换为字符(尝试str(as.vector(df1$test))了解我的意思;对于其他所有内容,它使用format,但不幸的是,没有选项可以包含来自 的任何参数format,其中一个是trim(默认情况下设置为FALSE)。

比较以下内容:

A <- c(TRUE, FALSE)

format(A)
# [1] " TRUE" "FALSE"
format(A, trim = TRUE)
# [1] "TRUE"  "FALSE"
format(as.character(A))
# [1] "TRUE " "FALSE"
format(as.factor(A))
# [1] "TRUE " "FALSE"

那么,如何轻松地将逻辑列转换为字符呢?也许是这样的(尽管我建议先创建数据备份):

df1[sapply(df1, is.logical)] <- lapply(df1[sapply(df1, is.logical)], as.character)
df1
#   test  logi
# 1    a  TRUE
# 2    b FALSE
# 3    < FALSE
# 4    >  TRUE
as.matrix(df1)
#      test logi   
# [1,] "a"  "TRUE" 
# [2,] "b"  "FALSE"
# [3,] "<"  "FALSE"
# [4,] ">"  "TRUE" 
于 2013-09-04T16:42:15.370 回答
1

肯定是由于应用,将数据框转换为矩阵,所以所有元素都具有相同的类型,这里是字符,逻辑转换为它。TRUE 被转换为 "TRUE" 以匹配 "FALSE" 的字符数:

"FALSE"
" TRUE"

要说服:

as.matrix(df)

相反,您可以使用 plyr 包中的 a*ply,例如

a_ply(df, 1, print)
于 2013-09-04T13:07:50.387 回答