在R中的范围内创建虚拟变量?

时间:2017-03-12 12:15:39

标签: r

数据集" dat"看起来像这样:

**V1  V2**  
1   2
2   2
3   5
9   8
9   9 
a   2

想要创建虚拟变量 V3

  1. if V1=V2, 0
  2. 否则,在1-8
  3. 的范围内

    如果涉及8+,或任何符号或字母,该变量应为NA。在上面的例子中,

    V3 = {0,1,0,NA,NA,NA}
    

2 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点。这个有一个循环,它检查每一行,并根据一组规则,返回你想要的任何东西。对于更复杂的规则,这很容易扩展。警告可以被忽略,因为它们是在" a"正在被强制数字化。

x <- read.table(text = "1   2
2   2
3   5
9   8
9   9 
a   2", header = FALSE)

x$V3 <- apply(x, MARGIN = 1, FUN = function(m) {
  xm <- as.numeric(as.character(m))

  if (!any(is.na(xm))) {
    if (any(xm > 8)) {
      return(NA)
    }
    if(xm[1] == xm[2]) {
      return(1)
    } else {
      return(0)
    }
  } else {
    return(NA)
  } 
})

  V1 V2 V3
1  1  2  0
2  2  2  1
3  3  5  0
4  9  8 NA
5  9  9 NA
6  a  2 NA

答案 1 :(得分:0)

这将是可以采取的众多方式之一。可能有一些更有效的方法:

# Create the original dataset
data <- data.frame(V1 = c(1,2,3,9,9,"a"), V2 = c(2,2,5,8,9,2))
# Check if V1 == V2 and write the result to V3 for ALL observations
data$V3 <- data$V1 == data$V2
# Where V1 or V2 are not in the range [1,8], overwrite V3 with NA
data$V3[!(grepl("\\b[12345678]\\b", data$V2) &
                grepl("\\b[12345678]\\b", data$V1))] <- NA

"\\b[12345678]{1,1}\\b"可以按如下方式分解:

1)[12345678]部分检查,如果字符串包含1:8范围内的某个数字。

2)\ bb ... \ bb部分为您提供单词边界 - 因此数字2将匹配,但数字28不匹配。

如果你想匹配范围0:13,你可以像这样调整正则表达式:

data$V3[!(grepl("\\b([0-9]|1[0-3])\\b", data$V2) &
                grepl("\\b([0-9]|1[0-3])\\b", data$V1))] <- NA

\\b([0-9]|1[0-3])\\b可以翻译如下:

1)[0-9]匹配数字0:9

2)1 [0-3]匹配数字10:13

3)[0-9] | 1 [0-3]告诉你数字0:9或10:13应匹配

4)\ b ... \ b为您提供单词边界

5)(...)告诉你应该在括号内的表达式之后评估单词边界。如果没有括号,这将是等效的操作:\\b[0-9]\\b|\\b1[0-3]\\b

有关将numeric rangesregular expression匹配的详细介绍,请参阅此链接:http://www.regular-expressions.info/numericranges.html