<?xml version="1.0" encoding="UTF-8"?><test>helloWorld</test>
每个科目(substring-after(/soap:Envelope/soap:Body/BusinessResponse/BusinessResult,'?>')
)都有不同类型的纵向考试(data.frame(id = rep(letters[1:2], each = 8), examID = as.character(c(11,11:17, 21:28)), baselineExam = c(rep(c(rbind('bl',c(11,14))), each = 2), c(rep('bl', 4), 21, 21, 24, 24)), examType = c("x", "x", "fu", "fu", "y", "z", "fu", "fu", "x", "x", "y", "z", "fu", "fu", "fu", "fu"), expected_col = c("x", "x", "x", "x", "y", "z", "y", "y", "x", "x", "y", "z", "x", "x", "z", "z"))
# the first four columns are my original data frame
# the last column shows the expected output.
id examID baselineExam examType expected_col
1 a 11 bl x x
2 a 11 bl x x
3 a 12 11 fu x
4 a 13 11 fu x
5 a 14 bl y y
6 a 15 bl z z
7 a 16 14 fu y
8 a 17 14 fu y
9 b 21 bl x x
10 b 22 bl x x
11 b 23 bl y y
12 b 24 bl z z
13 b 25 21 fu x
14 b 26 21 fu x
15 b 27 24 fu z
16 b 28 24 fu z
)。每次检查都有其唯一的标识符(examType
)。仅基准考试包含考试类型的信息。
后续检查仅包含信息“ fu”,而不包含正确的examType。但是,id
列显示了哪些是相应随访的基线检查。我想在每一行中有一列带有正确的examType。 (请参见数据框中的examID
)
我被困住了。我不能将baselineExam
之类的东西与expected_col
结合使用,因为没有可以用来区分这些考试的分组。
一种方法是获取相应“ fu”行的索引,在“ baselineExam”中查找该值,然后在“ examID”中查找该数字,以获取该行的examType
我尝试了一个带有索引号的辅助列(也必须有更好的方法),我可以在此行中获取基线检查的值-但我不知道如何有条件地在当(基线行的)examID ==(后续行的)extraExlineExam时的expressionType。
最好使用base R解决方案或dplyr,但可以开放使用
编辑
我更改了给定的数据,因为我以前的样本数据不能完全反映真实数据的复杂性(我简化了)。不幸的是,@www或@akrun的解决方案均无法正常工作-太糟糕了,因为我没有提供足够好的示例:( 每个考试ID可以有多行(长数据,在我的示例中为第1和2行),并且在进行后续考试之前,还要进行多次基础考试。
答案 0 :(得分:4)
使用dplyr
和tidyr
软件包的解决方案。关键是将fu
替换为NA
,然后使用fill
函数用上一行填充NA
。 mutate_if
只是将因子列转换为字符列。 dat2
是最终输出。
library(dplyr)
library(tidyr)
dat2 <- dat %>%
mutate_if(is.factor, as.character) %>%
mutate(type = ifelse(examType %in% "fu", NA, examType)) %>%
fill(type)
dat2
# id examID baselineExam examType type
# 1 a 11 bl x x
# 2 a 12 11 fu x
# 3 a 13 bl y y
# 4 a 14 13 fu y
# 5 b 21 bl x x
# 6 b 22 21 fu x
# 7 b 23 bl z z
# 8 b 24 23 fu z
我们可以使用dplyr
软件包来实现这一目标。首先,用已知的examType
子集数据帧,找到id
,examID
和examType
之间具有唯一组合的行,将表连接到原始数据帧,并使用coalesce
合并信息。
library(dplyr)
dat2 <- dat %>%
filter(!examType %in% "fu") %>%
distinct(id, examID, examType) %>%
rename(Type = examType) %>%
left_join(dat, ., by = c("id", "baselineExam" = "examID")) %>%
mutate(Type = coalesce(Type, examType))
dat2
# id examID baselineExam examType Type
# 1 a 11 bl x x
# 2 a 11 bl x x
# 3 a 12 11 fu x
# 4 a 13 11 fu x
# 5 a 14 bl y y
# 6 a 15 bl z z
# 7 a 16 14 fu y
# 8 a 17 14 fu y
# 9 b 21 bl x x
# 10 b 22 bl x x
# 11 b 23 bl y y
# 12 b 24 bl z z
# 13 b 25 21 fu x
# 14 b 26 21 fu x
# 15 b 27 24 fu z
# 16 b 28 24 fu z
dat <- data.frame(id = rep(letters[1:2], each = 8),
examID = as.character(c(11,11:17, 21:28)),
baselineExam = c(rep(c(rbind('bl',c(11,14))), each = 2), c(rep('bl', 4), 21, 21, 24, 24)),
examType = c("x", "x", "fu", "fu", "y", "z", "fu", "fu", "x", "x", "y", "z", "fu", "fu", "fu", "fu"),
stringsAsFactors = FALSE)
答案 1 :(得分:2)
一个选项是按'id'分组,并根据'bl'的出现创建分组变量,在'baselineExam'中将'type'创建为与'bl'相对应的'examType'
library(dplyr)
df1 %>%
group_by(id, grp = cumsum(baselineExam == 'bl')) %>%
mutate(type = examType[baselineExam == 'bl']) %>%
ungroup %>%
select(-grp)
# A tibble: 8 x 5
# id examID baselineExam examType type
# <fct> <fct> <fct> <fct> <fct>
#1 a 11 bl x x
#2 a 12 11 fu x
#3 a 13 bl y y
#4 a 14 13 fu y
#5 b 21 bl x x
#6 b 22 21 fu x
#7 b 23 bl z z
#8 b 24 23 fu z