使用 dplyr 根据条件改变多列
Mutate multiple columns with conditions using dplyr
我有一个大型数据集,我想为其创建 50 个新变量,其中的值以前面列中的值为条件,变量的名称反映了这一事实。为了方便理解,举个例子:
df <- tibble("a" = runif(10,1990,2000),
"event" = 1995) %>%
mutate("relative_event" = a - event)
现在有了这个数据集,我想创建虚拟变量,如果特定观察是在事件发生前一年、两年前等,以及向前进行编码。一种笨拙的方法(有效)是:
df <- df %>%
mutate("event_b1" = ifelse( (relative_event<=0) & (relative_event > -1),1,0)) %>%
mutate("event_b2" = ifelse( (relative_event<=-1) & (relative_event > -2),1,0)) %>% #etc with more lagx
mutate("event_f1" = ifelse( (relative_event>0) & (relative_event < 1),1,0)) %>%
mutate("event_f2" = ifelse( (relative_event>1) & (relative_event < 2 ),1,0)) #etc with more forward
其中 b1 代表 "one year before",f2 代表“2 年后”。结果如下所示:
A tibble: 10 x 7
a event relative_event event_b1 event_b2 event_f1 event_f2
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1993. 1995 -1.94 0 1 0 0
2 1992. 1995 -2.59 0 0 0 0
3 2000. 1995 4.75 0 0 0 0
4 1998. 1995 3.25 0 0 0 0
5 1991. 1995 -3.88 0 0 0 0
6 1992. 1995 -3.02 0 0 0 0
7 1996. 1995 1.08 0 0 0 1
8 1994. 1995 -1.04 0 1 0 0
9 1993. 1995 -2.22 0 0 0 0
10 1995. 1995 -0.302 1 0 0 0
因为我要创建 50 多个列,所以我想知道如何自动创建,这样我就不必复制粘贴 49 次并手动更改条件和变量名称。我花了时间在这个 , this 和 CV 上寻找 SO,但我仍然一无所知。我尝试了以下不起作用的代码:
for (i in 0:10) {
if (i<0) {
event_bi <- paste0("event_b",i)
df <- df %>%
mutate(get(event_bi) = ifelse((relative_event<=-(i-1)) & (relative_event>-i),1,0))
}
}
理想情况下,我想学习如何使用 dplyr 进行操作,但如果有明显的 Base R 解决方案,我也很乐意学习它。
谢谢!
我不会声称这是完整的答案,但希望这会刺激其他一些用户 comment/post
# load packages
pacman::p_load(tibble,dplyr,tidyr)
# your dataframe
df <- tibble("a" = runif(10,1990,2000),
"event" = 1995) %>%
mutate("relative_event" = round(a - event),0)
df$rel3 <- df$relative_event #initialize new column
for(xx in 1:(length(df$relative_event))) {
if (df$relative_event[xx] <=0) {
df$rel3[xx] <- paste0('b',as.character(abs(df$relative_event[xx])))
} else {
#add preceding a for "after"
df$rel3[xx] <- paste0('a',as.character(abs(df$relative_event[xx])))
}
}
然后您可以将 rel3
中的值转换为 df
中的列。
尽管我更喜欢按照@Patrick 的建议将所有变量都放在一列中的解决方案(尽管我会使用类似 %>% mutate(new_col = case_when(etc...))
的方法,这里是 for-loop
# I changed your data a tiny bit
df <- tibble("a" = sample(1990:2000, size = 10), # better to use 'sample' then 'runif' !
"event" = 1995) %>% mutate("relative_event" = a - event)
现在实际工作
for (i in min(df$relative_event):max(df$relative_event)) {
# the indexing value is your difference in years. So you have to run the index from the lowest difference to the highest.
if( i < 0 ) {
df[[paste0('event_b', abs(i))]] <- ifelse(i == df$relative_event, 1, 0)
}
if( i >= 0 ) {
df[[paste0('event_f', abs(i))]] <- ifelse(i == df$relative_event, 1, 0)
df
}
}
# A tibble: 10 x 14
a event relative_event event_b5 event_b4 event_b3 event_b2 event_b1
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1990 1995 -5 1 0 0 0 0
2 1992 1995 -3 0 0 1 0 0
3 1991 1995 -4 0 1 0 0 0
4 2000 1995 5 0 0 0 0 0
5 1998 1995 3 0 0 0 0 0
6 1993 1995 -2 0 0 0 1 0
7 1996 1995 1 0 0 0 0 0
8 1997 1995 2 0 0 0 0 0
9 1994 1995 -1 0 0 0 0 1
10 1999 1995 4 0 0 0 0 0
# ... with 6 more variables: event_f0 <dbl>, event_f1 <dbl>, event_f2 <dbl>,
# event_f3 <dbl>, event_f4 <dbl>, event_f5 <dbl>
如果您不想 运行 遍历所有可能的年份差异 -(这将创建 'empty' 列)- 您可以简单地创建一个包含 unique(df$relative_event)
和 运行 i
通过这个向量
我有一个大型数据集,我想为其创建 50 个新变量,其中的值以前面列中的值为条件,变量的名称反映了这一事实。为了方便理解,举个例子:
df <- tibble("a" = runif(10,1990,2000),
"event" = 1995) %>%
mutate("relative_event" = a - event)
现在有了这个数据集,我想创建虚拟变量,如果特定观察是在事件发生前一年、两年前等,以及向前进行编码。一种笨拙的方法(有效)是:
df <- df %>%
mutate("event_b1" = ifelse( (relative_event<=0) & (relative_event > -1),1,0)) %>%
mutate("event_b2" = ifelse( (relative_event<=-1) & (relative_event > -2),1,0)) %>% #etc with more lagx
mutate("event_f1" = ifelse( (relative_event>0) & (relative_event < 1),1,0)) %>%
mutate("event_f2" = ifelse( (relative_event>1) & (relative_event < 2 ),1,0)) #etc with more forward
其中 b1 代表 "one year before",f2 代表“2 年后”。结果如下所示:
A tibble: 10 x 7
a event relative_event event_b1 event_b2 event_f1 event_f2
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1993. 1995 -1.94 0 1 0 0
2 1992. 1995 -2.59 0 0 0 0
3 2000. 1995 4.75 0 0 0 0
4 1998. 1995 3.25 0 0 0 0
5 1991. 1995 -3.88 0 0 0 0
6 1992. 1995 -3.02 0 0 0 0
7 1996. 1995 1.08 0 0 0 1
8 1994. 1995 -1.04 0 1 0 0
9 1993. 1995 -2.22 0 0 0 0
10 1995. 1995 -0.302 1 0 0 0
因为我要创建 50 多个列,所以我想知道如何自动创建,这样我就不必复制粘贴 49 次并手动更改条件和变量名称。我花了时间在这个
for (i in 0:10) {
if (i<0) {
event_bi <- paste0("event_b",i)
df <- df %>%
mutate(get(event_bi) = ifelse((relative_event<=-(i-1)) & (relative_event>-i),1,0))
}
}
理想情况下,我想学习如何使用 dplyr 进行操作,但如果有明显的 Base R 解决方案,我也很乐意学习它。
谢谢!
我不会声称这是完整的答案,但希望这会刺激其他一些用户 comment/post
# load packages
pacman::p_load(tibble,dplyr,tidyr)
# your dataframe
df <- tibble("a" = runif(10,1990,2000),
"event" = 1995) %>%
mutate("relative_event" = round(a - event),0)
df$rel3 <- df$relative_event #initialize new column
for(xx in 1:(length(df$relative_event))) {
if (df$relative_event[xx] <=0) {
df$rel3[xx] <- paste0('b',as.character(abs(df$relative_event[xx])))
} else {
#add preceding a for "after"
df$rel3[xx] <- paste0('a',as.character(abs(df$relative_event[xx])))
}
}
然后您可以将 rel3
中的值转换为 df
中的列。
尽管我更喜欢按照@Patrick 的建议将所有变量都放在一列中的解决方案(尽管我会使用类似 %>% mutate(new_col = case_when(etc...))
的方法,这里是 for-loop
# I changed your data a tiny bit
df <- tibble("a" = sample(1990:2000, size = 10), # better to use 'sample' then 'runif' !
"event" = 1995) %>% mutate("relative_event" = a - event)
现在实际工作
for (i in min(df$relative_event):max(df$relative_event)) {
# the indexing value is your difference in years. So you have to run the index from the lowest difference to the highest.
if( i < 0 ) {
df[[paste0('event_b', abs(i))]] <- ifelse(i == df$relative_event, 1, 0)
}
if( i >= 0 ) {
df[[paste0('event_f', abs(i))]] <- ifelse(i == df$relative_event, 1, 0)
df
}
}
# A tibble: 10 x 14
a event relative_event event_b5 event_b4 event_b3 event_b2 event_b1
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1990 1995 -5 1 0 0 0 0
2 1992 1995 -3 0 0 1 0 0
3 1991 1995 -4 0 1 0 0 0
4 2000 1995 5 0 0 0 0 0
5 1998 1995 3 0 0 0 0 0
6 1993 1995 -2 0 0 0 1 0
7 1996 1995 1 0 0 0 0 0
8 1997 1995 2 0 0 0 0 0
9 1994 1995 -1 0 0 0 0 1
10 1999 1995 4 0 0 0 0 0
# ... with 6 more variables: event_f0 <dbl>, event_f1 <dbl>, event_f2 <dbl>,
# event_f3 <dbl>, event_f4 <dbl>, event_f5 <dbl>
如果您不想 运行 遍历所有可能的年份差异 -(这将创建 'empty' 列)- 您可以简单地创建一个包含 unique(df$relative_event)
和 运行 i
通过这个向量