基于R中循环中的条件进行错误赋值

bgibtngc  于 2023-04-18  发布在  其他
关注(0)|答案(2)|浏览(122)

如果值大于100,我尝试为df中的选定列分配“1”,否则为“0”。

vz201408  <- as.numeric(c("0.00","300.00","500.00","0.00","0.00","210","0.00","0.00","0.00","0.00"))
vz201409  <- as.numeric(c("0.00","200.00","200.00","500.00","0.00","500","100","0.00","0.00","0.00"))
vz201410 <- as.numeric(c("100","100","100","0.00","0.00","21.00","0.00","0.00","0.00","482"))
vz201411 <- as.numeric(c("0.00","600.00","900.00","100.00","120.00","0.00","50.00","0.00","800.00","664 "))
vz201412 <- as.numeric(c("30.00","40.00","50.00","0.00","9.00","8.00","1.00","4.00","0.00","0.00"))
vz201501 <- as.numeric(c("500.00","100.00","100.00","500.00","0.00","200.00","0.00","0.00","100.00","200.00"))
vz201502 <- as.numeric(c("500.00","100.00","100.00","500.00","0.00","200.00","0.00","0.00","100.00","200.00"))
vz201503 <- as.numeric(c("500.00","100.00","100.00","600.00","0.00","200.00","0.00","0.00","90.00","100.00"))
vz201604 <- as.numeric(c("50.00","10.00","10.00","400.00","100.00","200.00","0.00","0.00","10.00","20.00"))
vz201701 <- as.numeric(c("100.00","10.00","10.00","50.00","0.00","200.00","0.00","300.00","100.00","200.00"))
df <- data.frame(vz201408,vz201409, vz201410, vz201411,vz201412,vz201501,vz201502,vz201503,vz201604,vz201701)

我正在使用这个循环,但它错误地分配了1/0。即使值低于阈值100,它也会给出“1”。请提供任何建议?谢谢!

# Select only the following columns
col_indices <- grep("^vz2014(1[0-2])$|^vz2015\\d{2}$|^vz2016(0[1-9]|1[0-2])$", names(df))
col_names <- names(df)[col_indices]

for (c in col_names) {
  for (i in 1:length(col_names)) {
    df[, paste0('Empl_vz', i)] <- ifelse(df[, c] >= 100,
                                               1,
                                               0)
  }
}
yvt65v4c

yvt65v4c1#

如果您的c已经表示了一个列名,那么为什么还要迭代所有列呢?相反,我认为我们可以对列名进行seq_along并使用单个循环。(另外,您正在派生逻辑0/1,因此我们可以简化条件并删除ifelse。)
仅供参考,进程失败的原因是,虽然它正确地计算了每一列,但它覆盖了循环中上一次迭代的结果。您的基本操作失败了,只是您的循环应该准确地触发length(col_names)(这里是5)次,而不是触发5 * 5次,在第21-25次,它用col_names[5]中的列覆盖了所有列。

col_names <- grep("^vz2014(1[0-2])$|^vz2015\\d{2}$|^vz2016(0[1-9]|1[0-2])$", names(df), value=TRUE)
for (i in seq_along(col_names)) {
  df[, paste0("Empl_vz", i)] <- +(df[, col_names[i]] >= 100)
}
df
#    vz201408 vz201409 vz201410 vz201411 vz201412 vz201501 vz201502 vz201503 vz201604 vz201701 Empl_vz1 Empl_vz2 Empl_vz3 Empl_vz4 Empl_vz5 Empl_vz6 Empl_vz7
# 1         0        0      100        0       30      500      500      500       50      100        1        0        0        1        1        1        0
# 2       300      200      100      600       40      100      100      100       10       10        1        1        0        1        1        1        0
# 3       500      200      100      900       50      100      100      100       10       10        1        1        0        1        1        1        0
# 4         0      500        0      100        0      500      500      600      400       50        0        1        0        1        1        1        1
# 5         0        0        0      120        9        0        0        0      100        0        0        1        0        0        0        0        1
# 6       210      500       21        0        8      200      200      200      200      200        0        0        0        1        1        1        1
# 7         0      100        0       50        1        0        0        0        0        0        0        0        0        0        0        0        0
# 8         0        0        0        0        4        0        0        0        0      300        0        0        0        0        0        0        0
# 9         0        0        0      800        0      100      100       90       10      100        0        1        0        1        1        0        0
# 10        0        0      482      664        0      200      200      100       20      200        1        1        0        1        1        1        0

一个更快的方法,没有循环:

df[, paste0("Empl_vz", seq_along(col_names))] <- +(df[, col_names] >= 100)
df
#    vz201408 vz201409 vz201410 vz201411 vz201412 vz201501 vz201502 vz201503 vz201604 vz201701 Empl_vz1 Empl_vz2 Empl_vz3 Empl_vz4 Empl_vz5 Empl_vz6 Empl_vz7
# 1         0        0      100        0       30      500      500      500       50      100        1        0        0        1        1        1        0
# 2       300      200      100      600       40      100      100      100       10       10        1        1        0        1        1        1        0
# 3       500      200      100      900       50      100      100      100       10       10        1        1        0        1        1        1        0
# 4         0      500        0      100        0      500      500      600      400       50        0        1        0        1        1        1        1
# 5         0        0        0      120        9        0        0        0      100        0        0        1        0        0        0        0        1
# 6       210      500       21        0        8      200      200      200      200      200        0        0        0        1        1        1        1
# 7         0      100        0       50        1        0        0        0        0        0        0        0        0        0        0        0        0
# 8         0        0        0        0        4        0        0        0        0      300        0        0        0        0        0        0        0
# 9         0        0        0      800        0      100      100       90       10      100        0        1        0        1        1        0        0
# 10        0        0      482      664        0      200      200      100       20      200        1        1        0        1        1        1        0

+(.)工作的原因是通过R的类到类的强制。您可以对逻辑(TRUE/FALSE)进行基本的数学运算,因为R将其转换为1/0。最简单的数学运算是数字或表达式前的一元+。(尝试+TRUE+FALSE进行确认。)

nzk0hqpo

nzk0hqpo2#

不确定,但也许您希望输出具有原始数据框维度的数据框。使用if/else条件来标识所需的列。

cols <- grep("^vz2014(1[0-2])$|^vz2015\\d{2}$|^vz2016(0[1-9]|1[0-2])$", names(df))

df_new <- setNames(data.frame(sapply(seq_along(df), function(x)
  if(any(x == cols)){(df[,x] > 100) * 1} else{df[,x]})), colnames(df))

colnames(df_new)[cols] <- paste0("Empl_vz", 1:length(cols))

df_new
   vz201408 vz201409 Empl_vz1 Empl_vz2 Empl_vz3 Empl_vz4 Empl_vz5 Empl_vz6
1         0        0        0        0        0        1        1        1
2       300      200        0        1        0        0        0        0
3       500      200        0        1        0        0        0        0
4         0      500        0        0        0        1        1        1
5         0        0        0        1        0        0        0        0
6       210      500        0        0        0        1        1        1
7         0      100        0        0        0        0        0        0
8         0        0        0        0        0        0        0        0
9         0        0        0        1        0        0        0        0
10        0        0        1        1        0        1        1        0
   Empl_vz7 vz201701
1         0      100
2         0       10
3         0       10
4         1       50
5         0        0
6         1      200
7         0        0
8         0      300
9         0      100
10        0      200

相关问题