如果值等于列名,如何在 R 中的整个数据集中重新编码列中的值

How to recode values in a column if the value equals the column name, across an entire dataset in R

我有一个非常大的数据集,我正在尝试整理。这是我出于这个问题的目的而感兴趣的前几行变量中的几行:

id stressor
1 Homelessness
1 Inadequate Housing
5 Emotional Abuse
5 Extreme Poverty/Low Income
5 Physical Abuse
6 Chaotic atmosphere/stressful home environment

应激源变量是一个有 61 个水平的因素。这是一个对象的代码,其中包含您在 table:

中看到的内容
structure(list(id = c(1, 1, 5, 5, 5, 6), stressor = structure(c(4L, 
5L, 2L, 3L, 6L, 1L), .Label = c("Chaotic atmosphere/stressful home environment", 
"Emotional Abuse", "Extreme Poverty/Low Income", "Homelessness", 
"Inadequate Housing", "Physical Abuse"), class = "factor")), class = "data.frame", row.names = c(NA, 
-6L))

我正在尝试重塑数据,以便每个 ID 只有一行,每个压力源都有一列。理想情况下,如果此人有压力源,则对应于 id 和该压力源的值将为 1,否则为 0。我已经得到了尽可能投射数据。这是我为此使用的代码:

data_cast<-dcast(data, id ~ stressor)

之后,我有一个如下所示的数据框:

id Homelessness Inadequate Housing Emotional Abuse Extreme Poverty/Low Income Physical Abuse Chaotic atmosphere/stressful home environment
1 Homelessness Inadequate Housing NA NA NA NA
5 NA NA Emotional Abuse Extreme Poverty/Low Income Physical Abuse NA
6 NA NA NA NA NA Chaotic atmosphere/stressful home environment

现在这是正确的格式,但值不是我需要的。我希望最终结果如下所示:

id Homelessness Inadequate Housing Emotional Abuse Extreme Poverty/Low Income Physical Abuse Chaotic atmosphere/stressful home environment
1 1 1 0 0 0 0
5 0 0 1 1 1 0
6 0 0 0 0 0 1

我知道,对于每个单独的专栏,我可以做这样的事情来得到我想要的:

data_cast$Homelessness<-ifelse(data_cast$Homelessness == "Homelessness", 1, 0)

我知道在单个列的级别上执行此操作的几种方法,但我必须对每个变量重复该操作,实际数据中有 61 个。这将需要大量编码,我想避免这种情况。

如果在任何列名称中找到该值,是否有办法将数据中的值重新编码为等于 1?我正在尝试使用 ifelse()names() 但无法弄清楚测试参数的左侧会发生什么。我猜,如果可以这样做的话,它会是这样的:

data_cast<-ifelse(__________ %in% names(data_cast) == TRUE, 1, 0)

我只尝试了 data_cast %in% names(data_cast),以及 as.list(data_cast)[-1] %in% names(data_cast)unlist(data_cast) %in% names(data_cast),但是其中 none 有效。

谁能帮我解决这个问题?如果我需要提供更多信息,请告诉我,我很乐意这样做。我对 R 比较陌生,所以我试着在 SO 上查看其他问题,但如果已经有适用的答案,那么我一定对 R 了解不够,无法发现它们。抱歉,如果是这样的话。

可能的解决方案:

library(tidyverse)

data_cast %>% 
  mutate(across(!id, ~ ifelse(is.na(.x),0,1)))

可以使用 dcast 的 fun.aggregate 参数:

data_cast <- dcast(data, id ~ stressor, fun.aggregate = length)