【问题标题】:R how to implement if else in apply instead of for loopR如何在apply而不是for循环中实现if else
【发布时间】:2014-07-01 12:48:21
【问题描述】:

EX 数据:

Col1 Col2 
   1    a
   2    b
   3 null
   4    c

如何将 Col2 的所有 NULL 元素更改为某个预定义值。我的实际数据大约是 250,000 行,所以 for 循环会花费太多时间。我在考虑某种 apply / ddplyifelse 组合,但我似乎无法让它发挥作用。

更具体地说,如何将 for 循环更改为更有效的方法

for(I in 1:n)
{
  if(col2(I) == NULL)
    col2(I) = x
    else...nothing happens
}

【问题讨论】:

  • 如果您只需要对单个列执行此操作,则只需 ifelse。如果你想对很多列做同样的事情,apply 会派上用场。

标签: r loops if-statement data.table apply


【解决方案1】:

您可以使用ifelse 将值从null 更改为XXX

> dat <- read.table(h=T, text = "Col1 Col2 
  1     a
  2     b
  3     null
  4     c")
> dat
#   Col1 Col2
# 1    1    a
# 2    2    b
# 3    3 null
# 4    4    c
> dat$Col2 <- ifelse(dat$Col2 == 'null', 'XXX', dat$Col2)
> dat
#   Col1 Col2
# 1    1    1
# 2    2    2
# 3    3  XXX
# 4    4    3

另一种可能更容易理解的方法是

dat[,'Col2'] <- with(dat, ifelse(Col2 == 'null', 'XXX', Col2))

此外,如果您正在处理因素并且想要更改级别的名称,

> levels(dat$Col2)
## [1] "a"    "b"    "c"    "null"
> levels(dat$Col2)[4] <- "XXX"
> levels(dat$Col2)
## [1] "a"   "b"   "c"   "XXX"

【讨论】:

  • 或者如果它是一个真正的“null”值而不仅仅是单词“null”,那么使用 ifelse(is.null(dat$Col2), 'XXX', dat$Col2)跨度>
  • 得到错误 $ 运算符对原子向量无效
  • @MrFlick 是对的。如果值为NULL,请使用is.null。如果null,可能是因子水平或字符值。
  • @MathLover,你不需要用这个循环数据。我认为这就是您出现错误的原因?
  • @RichardScriven 实际上,您的解决方案更容易工作,因为原子向量不能有真正的null 值,只有NA。因此使用== 'null' 进行测试可能会得到正确的结果
【解决方案2】:

为什么不

Col2[Col2=="null"]<-"XXX"

注意 - 我认为您无法像这样在 data.frame 中获得真正的 NULL 值。

因素更新

回应@beginneR,

如果Col2factor,你可以这样做来改变它:

levels(Col2)<-c(levels(Col2),"XXX")
Col2[Col2=="null"]<-"XXX"

【讨论】:

  • 我也是这么想的。但是对于@Richard 的示例代码,这不起作用,因为 Col2 是 factor 并且“XXX”不是定义的因子级别。如果它是一个字符变量,这将起作用。
【解决方案3】:

这是一种使用data.table 的方法,它应该可以很好地扩展。

下面的示例有 100 万行,在我的笔记本电脑上花费的时间不到 1/10 秒。

# Load package data.table 
library(data.table)

# Set up data
Col1 <- rep(c(1,2,3,4), 250000)
Col2 <- rep(c("a", "b", "null", "c"), 250000)

# Define data as data.table
ex <- data.table(Col1, Col2)

# Substitute value "null" by "x" for variable "Col2"
ex[Col2=="null", Col2:="x"]

【讨论】:

  • 如果Col2character,那么df$Col2[df$Col2 == "null"] &lt;- "x" 在我的机器上需要0.084 秒,如果是factorlevels(df$Col2)[4] &lt;- "x" 甚至更快(0.030 秒)(基于您的示例1e6行数据)
【解决方案4】:

使用replace()怎么样?

R:> Col1 <- c(1,2,3,4)
R:> Col2 <- c("a", "b", "null", "c")
R:> ex <- data.frame(Col1, Col2)
R:> ex
   Col1 Col2
1    1    a
2    2    b
3    3 null
4    4    c
R:> typeof(ex$Col2)
[1] "integer"
R:> ex$Col2 <- as.character(ex$Col2)
R:> typeof(ex$Col2)
[1] "character"
R:> ex$Col2 <- replace(ex$Col2, which(ex$Col2 == "null"), "some")
R:> ex
  Col1 Col2
1    1    a
2    2    b
3    3 some
4    4    c
R:> 

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2022-01-10
    • 1970-01-01
    • 2017-08-02
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 2016-06-13
    相关资源
    最近更新 更多