T.McMillen
T.McMillen

Reputation: 137

How can I use the responses in multiple columns to create a new column?

I am trying to create a new column in my data frame based on the responses from other columns on the same row.

Most of the solutions that I have found are numeric and my scenario is character. I would like to create a new column that says "Detected" if any of the observations in that row say "Detected", if no observations say "Detected" then I would like the new columns response to be "Negative". In the scenario below I would like row 1 (ID 1) to have a 4th column (Test4) that says "Detected" based on the "Detected" response

ID <- c(1, 2, 3, 4)
Test1 <- c("Detected", "Not Detected", "Detected", "Detected")
Test2 <- c("Detected", "Not Detected", "Detected", "Detected")
Test3 <- c("Not Detected", "Detected", "Not Detected", "Not Detected")

df = data.frame(ID, Test1, Test2, Test3)

    ID     Test1       Test2           Test3
    1   Detected    Detected    Not Detected
    2   Not Detected Not Detected    Detected
    3   Detected    Detected    Not Detected
    4   Detected    Detected    Not Detected

Upvotes: 2

Views: 394

Answers (2)

arg0naut91
arg0naut91

Reputation: 14764

You could just do:

df$Test4 <- ifelse(rowSums(df == "Detected") > 0,
                   "Detected",
                   "Negative")

Output:

  ID        Test1        Test2        Test3    Test4
1  1     Detected     Detected Not Detected Detected
2  2 Not Detected Not Detected     Detected Detected
3  3     Detected     Detected Not Detected Detected
4  4     Detected     Detected Not Detected Detected

If the above doesn't work, you may have an issue with the structure of your strings (e.g. there may be additional spaces, or other characters around).

It would help if you post an original example of the data. You could also try:

df$Test4 <- ifelse(
  apply(df, 1, function(x) any(grepl("^(?!.*Not).*Detected.*$", x, perl = T))),
  "Detected",
  "Negative"
)

That means the matched row doesn't need to 100% correspond to Detected (without any space, etc.), but it just needs to be present somewhere - without the Not part.

Upvotes: 3

Sai SL
Sai SL

Reputation: 121

For this solution, rewrite your df and mutate as below:

df = data.frame(ID, Test1, Test2, Test3, stringsAsFactors=F)
df <- mutate(df, Test4 = ifelse('Detected' %in% c(Test1, Test2, Test3), 'Detected', 'Negative'))

  ID        Test1        Test2        Test3    Test4
1  1     Detected     Detected Not Detected Detected
2  2 Not Detected Not Detected     Detected Detected
3  3     Detected     Detected Not Detected Detected
4  4     Detected     Detected Not Detected Detected

Hope this helps!

Upvotes: 0

Related Questions