使用for和if在数据框中基于其他列添加列值

15

我有这样一个数据框:

     id        adit     diag1   diag2       
      2       3         4230    2234        
      3       5         3345    4456        
      4       6         4567    4467

我想使用下面的伪代码添加另外两列dse1dse2

if diag1 contains 4230 then dse1 = 1 else dse1 = 0

if diag2 contains 4567 then dse2 =1  else dse2 = 0

我使用了这个:

for (i in 1 : nrow(dse)){
  for (j in 3: ncol(dse)){
     if dse[i,j] %in% ("4320"){dse$dse1 = 1}
        else{dse$dse1 = 0}
    if dse[i,j] %in% ("4567"){dse$dse2 = 1}
        else{dse$dse2 = 0} 
  }
}

但是这些方法都不起作用。


以下所有答案都是正确的路线。然而,如果您正在使用 if/else,那么 else 必须与您的 if 语句的闭合 } 在同一行上。 - Justin
对于(i在1到nrow(dse)的范围内){ 对于(j在3到ncol(dse)的范围内){ 如果(dse [i,j] == 4230){ dse $ dse1 = 1 } 否则{ dse $ dse1 = 0 } 如果(dse [i,j] %in%(4567)) { dse $ dse2 = 1 } 否则{ dse $ dse2 = 0 } } } 我按照上述更改代码,没有出现错误,但结果不正确。为什么?谢谢 - user1582755
不确定你的评论的意思。您可以根据需要编辑您的问题。此外,如果下面的任何答案解决了问题,请通过单击问题旁边的绿色复选标记将其标记为已回答,以便我们都知道它已经解决。 - Justin
我知道问题所在,dse$dse1 应该是 dse$dse[i],而 dse$dse2 应该是 dse$dse2[i]。感谢您的帮助和答案。 - user1582755
6个回答

25

无需使用循环,只需使用ifelse,例如:

dse = within(dse, {
    dse1 = ifelse(diag1 == 4230, 1, 0)
    dse2 = ifelse(diag2 == 4567, 1, 0)
 })

谢谢。dse1可能有很多个诊断,这意味着如果dse [i,j]%in%(“ 2345”,“ 3456”,“ 5678”){dse1 = 1)。并且if代码有任何错误?如何进行更正? - user1582755
我不确定你想要什么,请在你的问题中添加更多信息。 - Paul Hiemstra
2
@user1582755 - 要调整代码以适应多个匹配,我认为你只需要像下面这样替换上面对应的行:dse1 = ifelse(diag1 %in% c(2345,3456,5678), 1, 0) - thelatemail
dse1 = 1 如果 diag1 或 diag2 等在 ('224','334','333' 等) 中; dse2 = 1 如果 diag1 或 diag2 或 diag3(如果有)在 ('444','435' 等) 中 - user1582755

13

不要使用if/else语句,使用向量化操作,例如:

dat$dse1 <- as.numeric(dat$diag1 == 4230)
dat$dse2 <- as.numeric(dat$diag2 == 4567)

+1个好答案,但是我认为使用 ifelse 更加透明一些。此外,您还可以拥有除了 01 之外的其他值。 - Paul Hiemstra
1
这绝对是最好的答案。ifelse(cond, 1, 0) 不应该被使用。 - Rich Scriven

5

像这样:

dse$dse1<-0
dse$dse2<-0
dse$dse1[dse$diag1==4230]<-1
dse$dse2[dse$diag2==4567]<-1

请自行寻找一份好的R语言教程(例如这个),并仔细阅读有关索引向量的内容。


感谢所有的回答。如果我们像这样更改语句: 如果diag1或diag2包含4230,则dse1 = 1,否则dse1 = 0 如果diag2或diag1包含4567,则dse2 = 1,否则dse2 = 0 并且有许多诊断中有许多代码,因此有许多dses。有什么简洁的答案? - user1582755

4
您可以使用transform
transform(dse, dse1 = as.numeric(diag1 == 4230),
               dse2 = as.numeric(diag2 == 4567))

谢谢。dse1可能有许多诊断,也就是说,如果dse[i,j] %in% ("2345","3456","5678") {dse1 =1 }。 - user1582755

0

你也可以使用:

ifelse():

dat <- data.frame(id = c(2,3,4), adit = c(3,5,6),diag1 = c(4230,3345,4567), diag2 =            c(2234,4567,4467))
dat$dse1 <- ifelse(dat$diag1 == 4230,1,0)
dat$dse2 <- ifelse(dat$diag2 == 4567,1,0)
dat

0
一种使用 tidyverse 的解决方案:
x = data.frame(id = c(2, 3, 4), 
               adit=c(3, 5, 6), 
               diag1=c(4230, 3345, 4567), 
               diag2=c(2234, 4456, 4467))

x %>% mutate(dse1 = if_else(diag1 == 4230, 1, 0), 
             dse2 = if_else(diag2 == 4567, 1, 0))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接