在数据框中创建一个新变量,其值取决于R中的另外两个变量

时间:2018-02-14 23:10:15

标签: r for-loop if-statement

我正在尝试在数据框中创建一个新变量,以指示某人是否曾在1988年接受过手术,或者是否在1988年去世,或者这些是否都适用。

我的数据类似于:

test <- data.frame(
ID = c(1:300),
hyst = c(rep(1985:2014, 10)),
death = c(rep(0,150),(rep(1985:2014,5)))
)

我的新变量(测试$ y1988)如果他们在1988年接受了手术,应该是'Y'但是没有死; 'D',如果他们在1988年去世;和“X”如果两者都没有发生。 我试过这个

test$y1988 <- for (i in nrow(test)) {
if(test$hyst[i] == 1988 & test$death[i] != 1988) {
"Y"
} else if (test$death[i] == 1988) {
"D"
} else {
"X"
}
}

代码似乎运行,没有错误消息;但是'test'中没有创建新的'y1988'变量。

我见过这两个问题,How to create a new r dataframe variable contingent on existing variables;和 Creating a new variable in R from two existing ones 这是相似的,但不幸的是我仍然无法让我的代码工作。

1 个答案:

答案 0 :(得分:3)

由于两个原因,您的for循环无效。首先,您需要告诉它循环1:nrow(test),而不是nrow(test),其次,您需要告诉R应该分配新值test的特定行。以下代码将正确运行:

for (i in 1:nrow(test)) {
  if(test$hyst[i] == 1988 & test$death[i] != 1988) {
    test$y1988[i] <- "Y"
  } else if (test$death[i] == 1988) {
    test$y1988[i] <- "D"
  } else {
    test$y1988[i] <- "X"
  }
}

您可能还想考虑矢量化解决方案。在基数R中,您可以这样做:

test$y1988 <- with(test, ifelse(hyst == 1988 & death != 1988, "Y",
                                ifelse(death == 1988, "D", "X")))

或者使用tidyverse和magrittr,你可以这样做:

library(tidyverse)
library(magrittr)  # for the %<>% command
test %<>% mutate(y1988 = case_when(hyst == 1988 & death != 1988 ~ "Y", death == 1988 ~ "D", T ~ "X"))