我有一个带有两个感兴趣变量的数据框:一个字符变量,它是每个obs的状态缩写,以及一个每个obs的区域代码。我还有一个列表,将一组可接受的区域代码与每个州相关联。
df <- data.frame(state=c("AL","CO","DE","TX"), region=c(1,2,3,4))
acceptable_regions <- list(AL=c(1,2), CO=1, DE=c(2,3), TX=(1:4))
我想创建一个虚拟变量,如果该区域包含在可接受的代码集中,则分配为“ 0”,否则为“ 1”。 我的第一个念头是使用ifelse(),但出现一个错误,提示递归索引在第2级失败。
df$far_away <- ifelse(df$region %in% acceptable_regions[[df$state]], 0,1)
我本以为ifelse会认识到我想通过df $ state进行索引,因为acceptable_regions[[df$state[i]]
是独立工作的。
如何根据变量“ state”的值提取所需的列表元素?当然要尽量避免for循环。
答案 0 :(得分:1)
我们可以使用map2
(来自purrr
)遍历“状态”和“ region”的对应值,从“”的值中提取“ acceptable_region”的list
元素状态”,检查是否为%in%
“区域”以获取逻辑vector
,并用as.integer
强制将其转换为二进制文件
library(tidyverse)
df %>%
mutate(far_away = map2_int(state, region, ~
as.integer(.y %in% acceptable_regions[[.x]])))
# state region far_away
#1 AL 1 1
#2 CO 2 0
#3 DE 3 1
#4 TX 4 1
或使用rowwise
df %>%
rowwise %>%
mutate(far_away = as.integer(region %in% acceptable_regions[[state]]))
#Source: local data frame [4 x 3]
#Groups: <by row>
# A tibble: 4 x 3
# state region far_away
# <fct> <dbl> <int>
#1 AL 1 1
#2 CO 2 0
#3 DE 3 1
#4 TX 4 1
或者与base R
一起使用Map
df$far_away <- as.integer(unlist(Map(function(x, y)
y %in% acceptable_regions[[x]], df$state, df$region)))