0

我有 2 个有序因子 A 和 B 的列表,它们都包含数千个项目,并且具有相同的序数规模,大约 30 个级别。我想找出 A 中有多少项目等于或在 B 中同一位置的项目之上或之下一级之内

如果这个比例是数字,我会将有序因子转换为数值,然后执行以下操作:

table(A==B || A==(B+1) || A==(B-1))

但是,当然,“+”对因子没有意义。那我该怎么办?我可以编写一个巨大的嵌套 if 语句,或者我也可以根据它们的级别将我的序数比例更改为数字,以便我可以将我的有序因子转换为数字......但这些似乎是我的一些迂回(和冗长)的解决方案d 假设很简单:如何增加或减少有序因子的水平?

如果我有

X<-ordered("b",levels=c("a","b","c"))

如何通过增加其当前级别来使其X[1]相等?"c"

旁注:当然,在上面的第一个示例中,我需要考虑规模上下端的因素,但我认为(希望)一旦我的问题得到回答,这很容易弄清楚.

4

3 回答 3

1

想出了一个办法。有人实际上发布了一个非常有用的答案,帮助我解决了这个问题,但突然无用/可悲地把它记下来了。我实际上想给他/她的信任。

对于我的 OP 中的示例,如果您执行以下操作,您将得到一个有序因子,其中 X[1] 变为“c”

 ordered(sapply(X,function(i){levels(i)[which(levels(i) == X[1]) + 1][1]}),levels=c("a","b","c"))

然后,您当然可以修改此代码以更改有序因子中特定元素的更改级别,还可以修改此代码以更改有序因子中的哪个元素正在更改。

于 2014-11-20T23:36:11.363 回答
1

I came along a similar problem and wrote a function that allows you to shift the levels of an ordered factor up and downwards.

  fct_shift_ord <- function(x, increment = 1, cap = TRUE, .fun = `+`){
    x_nlevel <- nlevels(x)
    x_lables <- levels(x)

  # apply function .fun to the numeric of the ordered vector
  erg <-.fun(as.numeric(x), increment)

  # cap to 1 and x_nlevel if the increment was larger than the original range of the factor levels
  if (cap) {
    erg[erg<1] <- 1
    erg[erg>x_nlevel] <- x_nlevel
  }
  ordered(erg, levels = 1:x_nlevel, labels = x_lables)
  }

so should work

table(A==B || A==fct_shift_ord(B,1) || A==fct_shift_ord(B,-1))
于 2017-10-25T16:43:42.960 回答
0

您应该能够修改此示例以获得所需的输出

set.seed(7)
df <- data.frame(A=sample(paste('A',seq(1:5),sep=''),5000,replace=TRUE),
                 B=sample(paste('A',seq(1:5),sep=''),5000,replace=TRUE))
table(df$A)
table(df$B)
fa=factor(levels(df$A))

ia=0
for (a in fa) {
  ia=ia+1
  cat('for factor',a,'\n')
  na = sum(df$A==a)
  nb = sum(df$B==a)
  cat('  df$A has',na,'\n')
  cat('  df$B has',nb,'\n')
  nbm1 = -1
  if (ia>1) {
    am1 <- fa[ia-1]
    nbm1 = sum(df$B==am1)
    cat('  df$B has',as.character(am1),', ',nbm1,'\n')
  }
  nbp1 = -1
  if (ia<length(fa)) {
    ap1 <- fa[ia+1]
    nbp1 = sum(df$B==ap1)
    cat('  df$B has',as.character(ap1),', ',nbp1,'\n')
  }
  if (na == nbm1) {
    cat('    df$A[a] has same number as df$B[a-1]\n')
  } else {
    cat('    df$A[a] does not have the same number as df$B[a-1]\n')
  }
  if (na == nbp1) {
    cat('    df$A[a] has same number as df$B[a+1]\n')
  } else {
    cat('    df$A[a] does not have the same number as df$B[a+1]\n')
  }
}
于 2014-11-12T01:52:11.327 回答