-->

什么是你整个运行最大的R-疑难杂症?(What's the biggest R-gotcha

2019-07-21 08:55发布

是否有过,你真的很惊讶有一天,一个特定的R-疑难杂症? 我想我们从共享这些所有的增益。

这里是我的:在列表索引, my.list[[1]]my.list[1] 在R.初期得知这个

Answer 1:

在数据帧中删除的行会导致非唯一命名的行要添加,然后出现了错误:

> a<-data.frame(c(1,2,3,4),c(4,3,2,1))
> a<-a[-3,]
> a
  c.1..2..3..4. c.4..3..2..1.
1             1             4
2             2             3
4             4             1
> a[4,1]<-1
> a
Error in data.frame(c.1..2..3..4. = c("1", "2", "4", "1"), c.4..3..2..1. = c(" 4",  : 
  duplicate row.names: 4

那么,什么是怎么回事是:

  1. 一个四列data.frame被创建,所以rownames是C(1,2,3,4)

  2. 第三行被删除,所以rownames是C(1,2,4)

  3. 第四行被添加,和R自动设置行名称等于索引即4,所以行的名称是C(1,2,4,4)。 这是非法的,因为行的名称应该是唯一的。 我不明白为什么这种类型的行为应该由R.被允许在我看来是R应该提供一个唯一的行名。



Answer 2:

[哈德利指出这一点在评论 ]

当使用序列作为迭代索引,最好使用seq_along()函数,而不是像1:length(x)

在这里,我创建一个载体,这两种方法返回同样的事情:

> x <- 1:10
> 1:length(x)
 [1]  1  2  3  4  5  6  7  8  9 10
> seq_along(x)
 [1]  1  2  3  4  5  6  7  8  9 10

现在让矢量NULL

> x <- NULL
> seq_along(x) # returns an empty integer; good behavior
integer(0)
> 1:length(x) # wraps around and returns a sequence; this is bad
[1] 1 0

这可能会导致在一个循环中的一些困惑:

> for(i in 1:length(x)) print(i)
[1] 1
[1] 0
> for(i in seq_along(x)) print(i)
>


Answer 3:

自动创建的因素,当你加载数据。 你不假思索地对待一个数据帧作为字符列,直到你这样做试图将值改为一个是不是一个级别的这个效果很好。 这将产生一个警告,但与NA在它留给你的数据帧...

当出现在你的[R脚本错误的意外,检查因素并不为怪。



Answer 4:

遗忘下拉=在子集FALSE参数矩阵下降到单个维度,从而丢弃对象类,以及:

R> X <- matrix(1:4,2)
R> X
     [,1] [,2]
[1,]    1    3
[2,]    2    4
R> class(X)
[1] "matrix"
R> X[,1]
[1] 1 2
R> class(X[,1])
[1] "integer"
R> X[,1, drop=FALSE]
     [,1]
[1,]    1
[2,]    2
R> class(X[,1, drop=FALSE])
[1] "matrix"
R> 


Answer 5:

首先,让我说,我理解在一个双星系统表示数字的根本问题。 然而,有一个问题,我认为可以很容易地改进是数字的表示时十进制值超出的r典型的表现范围。

x <- 10.2 * 100
x
1020
as.integer(x)
1019

如果结果表示为整数时,它真的可以表示为一个整数,我不介意。 例如,如果该值真的是1020然后打印,对于X就可以了。 但由于东西作为1020.0简单的在这种情况下,当打印X会变得更加明显,值不是一个整数,并不能表示为一个。 [R应该默认为某种迹象的时候有没有被提出了一个非常小的小数部分。



Answer 6:

它可以是恼人不得不允许的组合NANaNInf 。 他们不同的表现,并为一个测试不一定会为别人工作:

> x <- c(NA,NaN,Inf)
> is.na(x)
[1]  TRUE  TRUE FALSE
> is.nan(x)
[1] FALSE  TRUE FALSE
> is.infinite(x)
[1] FALSE FALSE  TRUE

然而,以测试这些闹事者的最安全的方法是:

> is.finite(x)
[1] FALSE FALSE FALSE


Answer 7:

始终测试当你有一个发生了什么NA

有一两件事,我总是需要认真注意(很多痛苦的经历之后) NA值。 R的功能和易于使用,但没有编程的方式将克服与您的数据的问题。

举例来说,与任何净向量运算NA等于NA 。 这是在它的面前“令人惊讶”:

> x <- c(1,1,2,NA)
> 1 + NA
[1] NA
> sum(x)
[1] NA
> mean(x)
[1] NA

这被外推到其他更高级的功能。

换句话说, 。 许多函数具有na.rm=TRUE/FALSE的默认值; 这是值得花一些时间决定如何解释这些默认设置。

马立克使一个伟大的点。 NA值也可能导致索引混乱行为。 例如:

> TRUE && NA
[1] NA
> FALSE && NA
[1] FALSE
> TRUE || NA
[1] TRUE
> FALSE || NA
[1] NA

这也是真实的,当你试图创建一个条件表达式(对于if语句):

> any(c(TRUE, NA))
[1] TRUE
> any(c(FALSE, NA))
[1] NA
> all(c(TRUE, NA))
[1] NA

当这些NA值,最终成为你的载体指标,很多意想不到的事情可以遵循。 这是所有R良好的行为,因为这意味着你必须要小心遗漏值。 但是,它可能会导致在一开始的主要难题。



Answer 8:

忘记了strptime()和朋友返回POSIXt POSIXlt其中length()始终是-九转换为POSIXct帮助:

R> length(strptime("2009-10-07 20:21:22", "%Y-%m-%d %H:%M:%S"))
[1] 9
R> length(as.POSIXct(strptime("2009-10-07 20:21:22", "%Y-%m-%d %H:%M:%S")))
[1] 1
R> 


Answer 9:

round函数总是四舍五入为偶数。

> round(3.5)
[1] 4  

> round(4.5)
[1] 4


Answer 10:

对整数数学是从双打略有不同(有时是复杂怪异太)

UPDATE他们固定的一些事情中的R 2.15

1^NA      # 1
1L^NA     # NA
(1+0i)^NA # NA 

0L %/% 0L # 0L  (NA from R 2.15)
0 %/% 0   # NaN
4L %/% 0L # 0L  (NA from R 2.15)
4 %/% 0   # Inf


Answer 11:

我很惊讶,没有人提到这一点,但是:

TF可以覆盖, TRUEFALSE没有。

例:

x <- sample(c(0,1,NA), 100, T)
T <- 0:10

mean(x, na.rm=T)
# Warning in if (na.rm) x <- x[!is.na(x)] :
#   the condition has length > 1 and only the first element will be used
# Calls: mean -> mean.default
# [1] NA

plot(rnorm(7), axes=T)
# Warning in if (axes) { :
#   the condition has length > 1 and only the first element will be used
# Calls: plot -> plot.default
# Warning in if (frame.plot) localBox(...) :
#   the condition has length > 1 and only the first element will be used
# Calls: plot -> plot.default

[编辑] ctrf+F欺骗我。 沙恩提及关于这在他的评论 。



Answer 12:

在数据读取可能比你想象的更困难。 今天,我发现,如果你使用read.csv(),如果.csv文件行是空的,read.csv()自动跳过它。 这是有道理的大多数应用程序,但如果你从自动(例如)27行从几千个文件中提取数据,以及一些前面的行可能会或可能不会是空白,如果你不小心的事情可以去可怕错误。

我现在用的

data1 <- read.table(file_name, blank.lines.skip = F, sep = ",")

当您要导入数据,请检查你在做什么,你真的认为你又来了一次又一次......



Answer 13:

在棘手的行为all.equal()函数。

我的一个连续的错误是比较一组浮点数。 我有一个像CSV:

... mu,  tau, ...
... 0.5, 1.7, ...

读取该文件,并试图子集,有时作品的数据,有时会失败 - 当然,由于落入浮点陷阱坑连连。 起初,该数据仅包含整数值,再后来就总是转换成真正的价值,你知道这个故事。 对比应该用做all.equal()函数,而不是==操作符,当然,代码我第一次写用后一种方法。

是啊,很酷,但all.equal()返回TRUE的人数相等,但如果失败的文本错误信息:

> all.equal(1,1)
[1] TRUE
> all.equal(1:10, 1:5)
[1] "Numeric: lengths (10, 5) differ"
> all.equal(1:10, c(1:5,1:5))
[1] "Mean relative difference: 0.625"

该溶液是用isTRUE()函数:

if (!isTRUE(all.equal(x, y, tolerance=doubleErrorRate))) {
    ...
}

多少次了我读all.equals()介绍...



Answer 14:

这一次受伤这么多,我花了几个小时添加注释的错误报告 。 我没有得到我的愿望,但至少R的下一个版本将产生一个错误。

R> nchar(factor(letters))
 [1] 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

更新:作为R 3.2.0(可能更早)的,本实施例中,产生错误消息。 如在下面的评论所提到的,一个因素是不是矢量和的nchar()需要的载体。

R> nchar(factor(letters))
Error in nchar(factor(letters)) : 'nchar()' requires a character vector
R> is.vector(factor(letters))
[1] FALSE


Answer 15:

  1. 由忘记包括空括号意外列出函数的源代码:例如“LS”相对于“LS()”

  2. 真假不剪作为预定义的常数,如在Matlab,C ++,使用Java,Python; 必须使用真假

  3. 看不见的返回值:例如“.packages()”返回任何内容,而‘(.packages())’返回封装基座名称的字符向量



Answer 16:

例如,该数目是3.14的数值常数,但表达式3.14和-3.14是对函数的调用+-

> class(quote(3.14))
[1] "numeric"
> class(quote(+3.14))
[1] "call"
> class(quote(-3.14))
[1] "call"

见第13.2约翰·钱伯斯书数据分析软件 -其中R编程



Answer 17:

零长度的向量具有一些怪癖:

R> kk=vector(mode="numeric",length=0)
R> kk
numeric(0)
R> sum(kk)
[1] 0
R> var(kk)
[1] NA


Answer 18:

在部分匹配$操作:本机适用于清单,同时也对data.frame

df1 <- data.frame(foo=1:10, foobar=10:1)
df2 <- data.frame(foobar=10:1)

df1$foo # Correctly gets the foo column
df2$foo # Expect NULL, but this returns the foobar column!!!

# So, should use double bracket instead:
df1[["foo"]]
df2[["foo"]]

[[操作也有一个exact标志,但它是值得庆幸的是TRUE默认。

部分匹配也影响attr

x1 <- structure(1, foo=1:10, foobar=10:1)
x2 <- structure(2, foobar=10:1)

attr(x1, "foo") # Correctly gets the foo attribute
attr(x2, "foo") # Expect NULL, but this returns the foobar attribute!!!

# So, should use exact=TRUE
attr(x1, "foo", exact=TRUE)
attr(x2, "foo", exact=TRUE)


Answer 19:

使用列表,有一对夫妇的事情直观:

当然,之间的区别[[[需要一些时间来适应。 对列表中, [而返回(潜在1)的元素的列表[[返回列表内的元件。

创建列表:

# When you're used to this:
x <- numeric(5) # A vector of length 5 with zeroes
# ... this might surprise you
x <- list(5)    # A list with a SINGLE element: the value 5
# This is what you have to do instead:
x <- vector('list', 5) # A vector of length 5 with NULLS

那么,如何插入NULL到一个列表?

x <- list("foo", 1:3, letters, LETTERS) # A sample list
x[[2]] <- 1:5        # Put 1:5 in the second element
# The obvious way doesn't work: 
x[[2]] <- NULL       # This DELETES the second element!
# This doesn't work either: 
x[2] <- NULL       # This DELETES the second element!

# The solution is NOT very intuitive:
x[2] <- list(NULL) # Put NULL in the second element

# Btw, now that we think we know how to delete an element:
x <- 1:10
x[[2]] <- NULL  # Nope, gives an ERROR!
x <- x[-2]    # This is the only way for atomic vectors (works for lists too)

最后,一些先进的东西,想通过一个嵌套列表索引:

x <- list(a=1:3, b=list(c=42, d=13, e="HELLO"), f='bar')
x[[c(2,3)]] # HELLO (first selects second element and then it's third element)
x[c(2,3)]   # The second and third elements (b and f)


Answer 20:

其中R中的大混乱的是, [i, drop = TRUE]不降因子水平,但[i, j, drop = TRUE]不!

> df = data.frame(a = c("europe", "asia", "oceania"), b = c(1, 2, 3))
> df$a[1:2, drop = TRUE]
[1] europe asia  
Levels: asia europe          <---- drops factor levels, works fine
> df[1:2,, drop = TRUE]$a
[1] europe asia  
Levels: asia europe oceania  <---- does not drops factor levels!

欲了解更多信息,请参阅: 降= TRUE不降在data.frame因子水平,而在矢量它



Answer 21:

自动矢量的重复用作索引(“循环”):

R> all.numbers <- c(1:5)
R> all.numbers
[1] 1 2 3 4 5
R> good.idxs <- c(T,F,T)
R> #note unfortunate length mismatch
R> good.numbers <- all.numbers[good.idxs]
R> good.numbers
[1] 1 3 4
R> #wtf? 
R> #why would you repeat the vector used as an index 
R> #without even a warning?


Answer 22:

从编译语言和Matlab的到来,我已经得到了偶尔困惑功能的基本方面功能性语言:他们正在使用之前被定义 ! 这是不够的只是让他们通过R解释解析。 这主要抚养当您使用嵌套函数发挥得淋漓尽致。

在Matlab中,你可以这样做:

function f1()
  v1 = 1;
  v2 = f2();
  fprintf('2 == %d\n', v2);

  function r1 = f2()
    r1 = v1 + 1 % nested function scope
  end
end

如果你试图做同样的事情在R,你必须首先把嵌套函数,或者你会得到一个错误! 仅仅因为你已经定义的功能,直到它分配给一个变量它不是在命名空间! 在另一方面,该功能可以指的是尚未定义的变量。

f1 <- function() {
  f2 <- function() {
    v1 + 1
  }

  v1 <- 1

  v2 = f2()

  print(sprintf("2 == %d", v2))
}


Answer 23:

从今天起煤矿:qnorm()以概率和pnorm()采用位数。



Answer 24:

对我来说,是当你使用一个data.frame导出到文本文件中的反直观的方式write.csv ,然后事后导入它,你需要添加一个额外的参数,以获得完全一样的data.frame,就像这样:

write.csv(m, file = 'm.csv')
read.csv('m.csv', row.names = 1) # Note the row.names argument

我还张贴了这个问题的SO和建议作为回答这个问答的@BenBolker。



Answer 25:

apply设定的功能不仅可为矩阵工作,但扩展到多维数组的。 在我的研究,我经常有对大气的例子温度的数据集。 这存储在多维阵列的尺寸x,y,level,time ,从现在开始称为multi_dim_array 。 一个样机的例子是:

multi_dim_array = array(runif(96 * 48 * 6 * 100, -50, 50), 
                        dim = c(96, 48, 6, 100))
> str(multi_dim_array)
#     x     y     lev  time    
 num [1:96, 1:48, 1:6, 1:100] 42.4 16 32.3 49.5 24.9 ...

使用apply可以很容易地获得:

# temporal mean value
> str(apply(multi_dim_array, 4, mean))
 num [1:100] -0.0113 -0.0329 -0.3424 -0.3595 -0.0801 ...
# temporal mean value per gridcell (x,y location)
> str(apply(multi_dim_array, c(1,2), mean))
 num [1:96, 1:48] -1.506 0.4553 -1.7951 0.0703 0.2915 ...
# temporal mean value per gridcell and level (x,y location, level)
> str(apply(multi_dim_array, c(1,2,3), mean))
 num [1:96, 1:48, 1:6] -3.839 -3.672 0.131 -1.024 -2.143 ...
# Spatial mean per level
> str(apply(multi_dim_array, c(3,4), mean))
 num [1:6, 1:100] -0.4436 -0.3026 -0.3158 0.0902 0.2438 ...

这使得margin参数apply似乎更直觉。 我第一次虽然,为什么不使用“行”和而不是1和2“山坳”但事实上,它也适用于阵列与多个维度清楚为什么使用margin这样是首选。



文章来源: What's the biggest R-gotcha you've run across?
标签: r r-faq