【问题标题】:apply prepends space for logical应用为逻辑添加空间
【发布时间】:2013-09-04 12:46:59
【问题描述】:

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] 上

版本 _
平台 x86_64-w64-mingw32
拱 x86_64
操作系统 mingw32
系统 x86_64、mingw32
状态
专业 3
次要 0.1
2013 年
05月
第 16 天
svn 版本 62743
语言 R
version.string R 版本 3.0.1 (2013-05-16) 昵称好运动

编辑: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

【问题讨论】:

  • 评论不允许代码。请稍等。
  • @AnandaMahto 查看我编辑的帖子。感谢您的回复!
  • 你能发布print(df, quote = TRUE)的输出吗?

标签: r space chr


【解决方案1】:

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

这里有几个例子可以帮助我详细说明我对 Karl 的查询。

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

  1. 您的原始data.frame 用于演示该行为:
  2. data.frame 在“测试”列中包含不同数量的字符,以查看 Karl 对发生情况的解释。
  3. data.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 之前有一个空格,但“test”列不受影响。嗯。

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

啊...这在TRUE 之前有一个空格, 在较短的数字之前有一个空格。所以看起来R可能正在考虑TRUEFALSE的数字基础值,但是计算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.matrixas.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" 

【讨论】:

  • 这很好!有了它,我可以在 apply/parApply 处理数据帧之前对其进行预编辑。尽管如此,我认为这对于数据框与应用函数的结合来说并不是适当的行为。也许这真的是错误的领土?我应该或某人将其发布到 R-bugtracker 吗?也许我对 R 的经验还不够丰富,无法意识到它的“积极”或“有用”的基本概念。
  • 是的,感谢您的努力,非常善于分析 :) 我现在更改了我的整个代码库,因此所有给出的逻辑列表首先都是字符串。感觉不舒服或不正确,但它有效。我不必通过修剪我拥有的每一个逻辑列来减慢我的计算过程。
【解决方案2】:

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

"FALSE"
" TRUE"

说服:

as.matrix(df)

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

a_ply(df, 1, print)

【讨论】:

  • 啊我现在明白了。 @AnandaMahto 是对的, print(df, quote = TRUE) 也确实添加了空格,但我仍然能够做到 df[1,1]==TRUE。除了 plyr 还有其他方法吗?我需要并行包的 paraapply,它具有相同的行为。
  • 你真的用其他例子测试过这个吗?我觉得这个答案不太对。
  • df1 &lt;- data.frame(test=c("a","bb","&lt;&lt;","&gt;"),logi=c(TRUE,FALSE,TRUE,TRUE)) 上试试你的解释。为什么第一列没有多余的空格?
  • 是的,没错,但您仍然可以执行类似 df1[3,2]==TRUE 的操作,而这在 apply 函数中不起作用。
  • plyr 还通过 .parallel 选项提供并行化
猜你喜欢
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
相关资源
最近更新 更多