我有这个名为' jobdata'
names <- c("person1", "person2", "person3")
job1_1_sector <- c("Private", "Public", "Private")
job2_1_sector <- c(NA, "Public", "Private")
job2_2_sector <- c("Private", "Public", "Other")
job3_1_sector <- c("Private", "Private", "Private")
job3_2_sector <- c("Other", "Public", "Other")
job3_3_sector <- c("Private", NA, "Private")
jobs <- cbind(job1_1_sector, job2_1_sector, job2_2_sector, job3_1_sector,
job3_2_sector, job3_3_sector )
jobdata <- data.frame(names, jobs)
如果单词Private出现,我想创建一个新的二进制变量private
,如果跨越相关变量(即job [123] _ [123] _sector),则等于1。然后另一个用于Public
,另一个用于Other
。我已经弄清楚如何在ifelse和grepl中使用它,但看起来我的代码行很长。有更简单的方法吗?
下面的代码为我提供了我想要的代码:
jobdata$private <- ifelse(grepl("Private", jobdata$job1_1_sector) | grepl("Private", jobdata$job2_1_sector) | grepl("Private", jobdata$job2_2_sector) | grepl("Private", jobdata$job3_1_sector) | grepl("Private", jobdata$job3_2_sector) | grepl("Private", jobdata$job3_3_sector), 1, 0)
jobdata$public <- ifelse(grepl("Public", jobdata$job1_1_sector) | grepl("Public", jobdata$job2_1_sector) | grepl("Public", jobdata$job2_2_sector) | grepl("Public", jobdata$job3_1_sector) | grepl("Public", jobdata$job3_2_sector) | grepl("Public", jobdata$job3_3_sector), 1, 0)
jobdata$other <- ifelse(grepl("Other", jobdata$job1_1_sector) | grepl("Other", jobdata$job2_1_sector) | grepl("Other", jobdata$job2_2_sector) | grepl("Other", jobdata$job3_1_sector) | grepl("Other", jobdata$job3_2_sector) | grepl("Other", jobdata$job3_3_sector), 1, 0)
谢谢!
答案 0 :(得分:3)
对于复杂的操作,首先将操作转换为函数然后将其应用于每个案例通常很有用。例如,
get_sector <- function(x, sector) {
apply(x, 1, function(y) {
as.numeric(any(grepl(sector, y), na.rm = TRUE))
})
}
jobdata$private <- get_sector(jobdata, "Private")
jobdata$public <- get_sector(jobdata, "Public")
jobdata$other <- get_sector(jobdata, "Other")
答案 1 :(得分:1)
tidyverse / dplyr 解决方案是首先将多个作业列压缩为一组标签和值:
library(tidyverse)
jobdata.long <- jobdata %>%
gather(job.number, sector, -names)
names job.number sector
1 person1 job1_1_sector Private
2 person2 job1_1_sector Public
3 person3 job1_1_sector Private
4 person1 job2_1_sector <NA>
5 person2 job2_1_sector Public
6 person3 job2_1_sector Private
7 person1 job2_2_sector Private
8 person2 job2_2_sector Public
9 person3 job2_2_sector Other
...
然后将正则表达式应用于新创建的&#34;扇区&#34;列,可能与summarize
一起为每个人和类别获取一个TRUE / FALSE标志:
job.types <- jobdata.long %>%
group_by(names) %>%
summarize(
private = any(grepl('Private', sector)),
public = any(grepl('Public', sector)),
other = any(grepl('Other', sector))
)
names private public other
<fctr> <lgl> <lgl> <lgl>
1 person1 TRUE FALSE TRUE
2 person2 TRUE TRUE FALSE
3 person3 TRUE FALSE TRUE
答案 2 :(得分:0)
您可以像这样使用非常强大的(s)apply
系列:
# define the types
type <- c("Private", "Public", "Other")
# columns in question
mask <- grepl("^job\\d+_\\d+_sector", colnames(jobdata))
# apply(..., 1, ...) means row-wise
jobdata[type] <- t(apply(jobdata[mask], 1, function(x) {
(s <- sapply(type, function(y) {
as.numeric(y %in% x)
}))
}))
这会产生
names job1_1_sector job2_1_sector job2_2_sector job3_1_sector job3_2_sector job3_3_sector Private Public Other
1 person1 Private <NA> Private Private Other Private 1 0 1
2 person2 Public Public Public Private Public <NA> 1 1 0
3 person3 Private Private Other Private Other Private 1 0 1