【问题标题】:How to expand Posixct field in R str()?如何扩展 R str() 中的 Posixct 字段?
【发布时间】:2017-10-17 00:26:31
【问题描述】:

我正在尝试扩展一个自定义 Posixct 字段中显示的因子数量,其中正常方式 (str(DF, list.len=ncol(DF), vec.len=20)) 不起作用。 我在这里请求 20,但无论列表的长度如何,它始终显示两个 ("2017-01-01 08:40:00" "2017-01-01 08:50:00" ...) (这里3)。 资料data.csv

"AAA", "BBB"
1, 01012017-0940+0100
2, 01012017-0950+0100
3, 01012017-0838+0100

代码

library('methods') # setClass

# https://unix.stackexchange.com/a/363290/16920
setClass('iso8601')

# https://stackoverflow.com/questions/5788117/only-read-limited-number-of-columns
setAs("character","iso8601",function(from) strptime(from,format="%d%m%Y-%H%M%z"))

DF <- read.csv(file='data.csv',
        sep=',',
        header=TRUE,
        colClasses=c('numeric','iso8601'),
        strip.white=TRUE)

DF

str(DF, list.len=ncol(DF), vec.len=20)

R 3.3.3 中的输出

 AAA                 BBB
1  1 2017-01-01 08:40:00
2  2 2017-01-01 08:50:00
3  3 2017-01-01 07:38:00
'data.frame':  3 obs. of  2 variables:
 $ AAA : num  1 2 3
 $ BBB : POSIXlt, format: "2017-01-01 08:40:00" "2017-01-01 08:50:00" ...

R 3.4.0 中的输出

同上,重现同样的问题。

  AAA                 BBB
1   1 2017-01-01 08:40:00
2   2 2017-01-01 08:50:00
3   3 2017-01-01 07:38:00
'data.frame':   3 obs. of  2 variables:
 $ AAA: num  1 2 3
 $ BBB: POSIXlt, format: "2017-01-01 08:40:00" "2017-01-01 08:50:00" ...
  1. 如何将str(DF, list.len=ncol(DF), vec.len=20) 扩展到每个变量的多个因子?

  2. 如何在str(DF) 中显示每个变量的项目数量?等不扩展参数本身在变量中。

消除病因中的终端宽度和列因素

我做到了

  1. 增加了默认值:宽度从 80 增加到 150,列从 24 增加到 38
  2. 重启终端提示
  3. 运行Rscript myScript.r
  4. 再次输出相同的结果,因此终端宽度和列数在这里似乎没有影响

罗兰的提议

该代码并非在所有场合都有效,但在有限的情况下,因此应该可以动态应用它

# Roland's comment
str(DF, list.len=ncol(DF), vec.len=20, width = 100)

R:3.3.3、3.4.0(2017-04-21,向后移植)
操作系统:Debian 8.7
窗口管理器:Gnome 3.14.1

【问题讨论】:

  • 您在问题标题中写入 POSIXct,然后创建一个 POSIXlt 变量。如果你创建了一个 POSIXct 变量,你可能不会遇到这个问题。
  • 1.我无法用 R 3.4.0 重现。我看到了预期的结果。 2. 使用as.POSIXct 而不是strptime。很少有理由将时间戳存储为 POSIXlt。
  • cran.r-project.org阅读debian的官方说明。
  • 我在我的 Mac 上再次尝试以确保它不是赢与 *nix 的事情。 如果控制台的宽度足够,它会按预期工作。试试str(DF, list.len=ncol(DF), vec.len=20, width = 100)
  • str 中的width = 参数设置为足够大的数字对我有用。 @Roland 已经提出了这个建议,但我没有看到你的回复评论。你能确认这对你不起作用吗?

标签: r posixct


【解决方案1】:

提案宽度

为了实现“更宽”的输出,您可以在 R options 中更改默认的width

根据options {base}求助:

宽度:

控制用于打印向量、矩阵和数组以及由 cat 填充时使用的行上的最大列数。

Here is an example:
# initial try
str(DF, list.len=ncol(DF), vec.len=20)

它给出:

    'data.frame':   3 obs. of  2 variables:
 $ AAA: num  1 2 3
 $ BBB: POSIXlt, format: "2017-01-01 11:40:00" "2017-01-01 11:50:00" ...

建议选项(宽度)

现在,用不同的width

# retain default options
op <- options()

# set apropriate width
n_cols <- 22 * 20 # n columns for 20 POSIXlt strings
n_cols <- n_cols + 50 # 50 columns for column description
# actually you can use any sufficiently big number
# for example n_cols = 1000
options(width = n_cols)
str(DF, list.len=ncol(DF), vec.len=20)
options(op)

结果是:

'data.frame':   3 obs. of  2 variables:
 $ AAA: num  1 2 3
 $ BBB: POSIXlt, format: "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00"

罗兰的宽度参数

看来您也可以使用str 中的width 参数来实现这一点。正如罗兰建议的那样。但同样你必须为输出提供足够大的价值。 1 个 POSIXlt 字符串包含 21 个字符 + 空格。因此,对于 20 个字符串,您需要超过 440 列。

三参数方法

我已经用你的例子试过了:

DF <- rbind(DF, DF, DF) # nrows = 24

# Calculate string width
string_size <- nchar(as.character(DF[1, 2])) + 3 # string width + "" and \w
N <- 20 # number of items
n_cols <- string_size * N

str(DF, list.len=ncol(DF), vec.len=20, width = n_cols)

输出:

'data.frame':   24 obs. of  2 variables:
 $ AAA: num  1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
 $ BBB: POSIXlt, format: "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00" "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00" "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00" "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00" "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00" "2017-01-01 11:40:00" "2017-01-01 11:50:00" "2017-01-01 10:38:00" "2017-01-01 11:40:00" "2017-01-01 11:50:00" ...

正好有 20 个 POSIXlt 字符串。

说明

输出问题来自于为 POSIXlt 对象调用的utils:::str.POSIXt 方法。有趣的部分在下一行:

larg[["vec.len"]] <- min(larg[["vec.len"]], (larg[["width"]] - 
                nchar(larg[["indent.str"]]) - 31)%/%19)

这一行计算输出中 POSIXlt 字符串的数量。粗略地说输出将不超过vec.lenPOSIXlt 字符串,并且输出的字符长度将不超过width

这里,larg 是传递给str 的参数列表。默认情况下,它们是: vec.len = 4; width = 80; indent.str = " ".

因此,重新计算的vec.len 默认为 2。

至于最后一个例子,我们设置了vec.len = 20width = 440,我们的数据框有24行。重新计算的vec.length 是20。所以输出str(DF) 包含20 个POSIXlt 字符串并以'...' 结尾,这意味着POSIXlt 向量中有超过20 个元素。

【讨论】:

  • 您可以让N &lt;- 20; stringSize &lt;- 22; n_cols &lt;- stringSize * N; 使算法依赖于每个字符串的字符数乘以字符串的数量。所以这个问题似乎取决于至少两个变量。你还能想点别的吗?
  • 我已经更新了正确变量声明的答案。现在,string_size 是用nchar 计算的,因此更容易使用不同的格式。另外,我现在想不出别的了。
  • 你能说一下为什么你在最后一个输出的末尾有...吗?我认为它应该是一个完整的输出,但它不是。你能提供任何理由吗?
  • 我为你提供赏金,因为你试图回答这个难题。我还不知道你的提议到底有多可靠。还有一些事情需要澄清。
  • 我添加了一些关于如何计算输出字符串长度的解释。对不起我的英语,希望它有意义。
猜你喜欢
  • 2013-02-21
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 2010-10-24
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多