【发布时间】:2022-01-24 03:44:23
【问题描述】:
我有一些调查数据,其中列出了某个事件是在一个月内发生,还是每个月都发生。如果被访者回答该事件发生在每个月,则各个月份都为 0,并且在下面的 same_all_year_round 列中为 1。
> dput(df[1:13])
structure(list(jun = c(0, 0, 1, 0), jul = c(0, 0, 0, 0), aug = c(1,
0, 0, 0), sep = c(0, 0, 0, 0), oct = c(1, 0, 0, 0), nov = c(0,
0, 0, 0), dec = c(1, 0, 0, 1), jan = c(0, 0, 0, 0), feb = c(1,
0, 1, 0), mar = c(0, 0, 1, 0), apr = c(1, 0, 0, 0), may = c(0,
0, 0, 0), same_all_year_round = c(0, 1, 0, 0)), row.names = c(NA,
-4L), class = "data.frame")
如果受访者回答该事件发生在每个月,我想用 1 填充每个单独的月份列。如下:
jun <- c(0, 1, 1, 0)
jul <- c(0, 1, 0, 0)
aug <- c(1, 1, 0, 0)
sep <- c(0, 1, 0, 0)
oct <- c(1, 1, 0, 0)
nov <- c(0, 1, 0, 0)
dec <- c(1, 1, 0, 1)
jan <- c(0, 1, 0, 0)
feb <- c(1, 1, 1, 0)
mar <- c(0, 1, 1, 0)
apr <- c(1, 1, 0, 0)
may <- c(0, 1, 0, 0)
same_all_year_round <- c(0, 1, 0, 0)
df <- data.frame(jun, jul, aug, sep, oct, nov, dec, jan, feb, mar, apr, may, same_all_year_round)
我有以下代码(正在运行),但更愿意遵循 DRY 规则。为简洁起见,我只包括了 3 个月。
df <- df %>%
mutate(jul = if_else(same_all_year_round == 1, 1, 0),
aug = if_else(same_all_year_round == 1, 1, 0),
sep = if_else(same_all_year_round == 1, 1, 0))
我应该使用 apply 版本吗?我尝试了几种不同的方法,但似乎没有任何效果。
【问题讨论】:
-
if_else返回一个与输入长度相同的向量。如果不将输入增加三倍,就无法将输出增加三倍。但是你不应该重复自己,如果所有这些列都相同,请使用jul = if_else(...), aug = jul, sep = jul)。 -
或者如果这些列已经存在,你可以使用
across,比如mutate(across(jan:dec, ~if_else(same_all_year_round == 1, 1, 0)))。一些样本输入和所需的输出将更容易看出哪些解决方案是可行的。 -
same_all_year_round似乎已经是二分法了,请尽可能运行dput(head(df))并从控制台复制结果。 -
@GregorThomas,这听起来很像我需要做的。我现在将添加一个示例输入和输出,以确保。谢谢!
-
但是我们已经可以看到另一个错误——如果
same_all_year_round是0,您不希望每个月都是0,您希望在这种情况下每个月都保持不变。所以mutate(across(jul:jun, ~if_else(same_all_year_round == 1, 1, .x)))应该可以工作。在包含合适的测试数据之前未经测试。