【问题标题】:replace factor values with next higher factor levels用下一个更高的因子水平替换因子值
【发布时间】:2021-04-13 13:48:28
【问题描述】:

我对 R 中的因子有疑问。 我想用下一个更高的因子水平替换一个因子的值。 这是一个例子:

假设我的因子有:

set.seed(1)

have <- sample(1:20, 10, TRUE)
have
#  [1]  4  7  1  2 11 14 18 19  1 10

我想要的是这个

[1] 7    10   2    4    14   18   19   <NA> 2    11

因此,每个值都被替换为下一个最高因子值/级别(4 变为 7,7 变为 10 等),并且最高值被替换为 NA。

实现这一目标的一种方法是

want <- factor(have)
levels(want) <- c(levels(want)[-1], NA)
want
# [1] 7    10   2    4    14   18   19   <NA> 2    11  
# Levels: 2 4 7 10 11 14 18 19

还有其他方法吗?

我收到了三个非常好的答案,我将在这里尝试总结一下:

func_lookup <- function(x){
  lu <- sort(unique(x))
  lu <- "[<-"(NA, lu, c(lu[-1], NA))
  lu[x]
}

func_dplyr <- function(x){
  levels(x) <- dplyr::lead(levels(x))
  x
}

func_base <- function(x){
  vals <- sort(unique(x))
  vals[match(x, vals) + 1]
}

从示例中可以看出,func_lookup 仅适用于向量,而 func_dplyr 仅适用于因子。 func_base 适用于因子和向量。

# Example 1
set.seed(1)
# create sample data
have <- c(4, 6, 6, 7)

# create sample data as factor
have_f <- factor(have)

# test functions for factor
have_f
func_lookup(have_f)
func_dplyr(have_f)
func_base(have_f)


#> have_f
#[1] 4 6 6 7
#Levels: 4 6 7
#> func_lookup(have_f)
#[1]  2  3  3 NA
#> func_dplyr(have_f)
#[1] 6    7    7    <NA>
#Levels: 6 7
#> func_base(have_f)
#[1] 6    7    7    <NA>
#Levels: 4 6 7

# for vectors
func_lookup(have)
func_base(have)

> func_lookup(have)
[1]  6  7  7 NA
> #func_dplyr(have)
> func_base(have)
[1]  6  7  7 NA

【问题讨论】:

  • 很高兴您找到了问题的答案!但是,请注意,您最初的目标是什么仍然有些不清楚。您的问题强调研究一个因素。事实上,GKi 公认的解决方案不适用于因子

标签: r factors


【解决方案1】:

sorthaveunique 值,使用match 获取它们的索引位置,加+1 得到下一个值并将其子集。

vals <- sort(unique(have))
vals[match(have, vals) + 1]
#[1]  7 10  2  4 14 18 19 NA  2 11

【讨论】:

    【解决方案2】:

    这个怎么样(你需要dplyr 包):

    levels(want) <- dplyr::lead(levels(want))
    
    > want
    ## [1] 7    10   2    4    14   18   19   <NA> 2    11  
    ## Levels: 2 4 7 10 11 14 18 19
    

    【讨论】:

      【解决方案3】:

      假设您正在使用整数值,有足够的内存并希望多次执行此操作,您可以创建一个带有间隙的查找表以允许直接访问下一个值。

      lu <- sort(unique(have))
      lu <- "[<-"(NA, lu, c(lu[-1], NA))
      
      lu[have]
      # [1]  7 10  2  4 14 18 19 NA  2 11
      

      如果你已经有factor,你可以试试:

      levels(want)[-1][want]
      # [1] "7"  "10" "2"  "4"  "14" "18" "19" NA   "2"  "11"
      
      levels(want)[unclass(want)+1]
      # [1] "7"  "10" "2"  "4"  "14" "18" "19" NA   "2"  "11"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-13
        • 1970-01-01
        • 2021-03-13
        相关资源
        最近更新 更多