我需要重新创建一个非常大的数据帧的原始变量(900+个变量)。 这是我正在尝试做的一个例子:
dat <- data.frame(
id=c('user1','user2','user3'),
agePanel1=c(20,25,32),
agePanel2=c(21,NA,33),
favColPanel1=c('blue','red','blue'),
favColPanel2=c('red',NA,'red')
)
id agePanel1 agePanel2 favColPanel1 favColPanel2
1 user1 20 21 blue red
2 user2 25 NA red NA
3 user3 32 33 blue red
对于每个变量,我需要在有面板数据的情况下创建一个新变量(age和favCol,以下是NA),否则是第一个面板观察。在面板数据不完整的情况下,所有面板值都应设置为NA。此示例的结果如下所示:
id age agePanel1 agePanel2 favCol favColPanel1 favColPanel2
1 user1 NA 20 21 NA blue red
2 user2 25 NA NA red NA NA
3 user3 NA 32 33 NA blue red
我开始尝试使用dplyr和tidyr:
mutate(dat, age = ifelse(is.na(test$agePanel2),agePanel1,NA))
我正在努力寻找一种方法来做一个循环或可以自动化这个过程的东西。
答案 0 :(得分:1)
您可以遍历要操作的列组的名称,对每个列进行操作:
cols <- c("age", "favCol")
for (col in cols) {
dat[,col] <- dat[,paste0(col, "Panel1")]
dat[!is.na(dat[,paste0(col, "Panel2")]), col] <- NA
dat[is.na(dat[,paste0(col, "Panel2")]),paste0(col, "Panel1")] <- NA
}
dat
# id agePanel1 agePanel2 favColPanel1 favColPanel2 age favCol
# 1 user1 20 21 blue red NA <NA>
# 2 user2 NA NA <NA> <NA> 25 red
# 3 user3 32 33 blue red NA <NA>
答案 1 :(得分:1)
您可以使用Map
dat[c('age', 'favcol')] <-Map(function(x,y) {
indx <- rowSums(is.na(cbind(x,y)))
x[seq_along(x)*NA^!indx]}, dat[c(2,4)], dat[c(3,5)])
dat[rowSums(is.na(dat[2:5]))!=0,2:5] <- NA
dat
# id agePanel1 agePanel2 favColPanel1 favColPanel2 age favcol
#1 user1 20 21 blue red NA <NA>
#2 user2 NA NA <NA> <NA> 25 red
#3 user3 32 33 blue red NA <NA>
答案 2 :(得分:1)
这不是您原始问题的最直接解决方案。但在我看来,将数据放在很长的时间里是可取的。然后你想要做的操作(和大多数其他操作)会容易得多。
# required packages
require(dplyr)
require(tidyr)
# get data in long format
dat_long <- dat %>%
gather(key, value, -id) %>%
separate(key, c("key", "panel"), sep = "Panel") %>%
spread(key, value, convert = TRUE) %>%
arrange(id, panel) %>%
group_by(id)
dat_long
## Source: local data frame [6 x 4]
## Groups: id
##
## id panel age favCol
## 1 user1 1 20 blue
## 2 user1 2 21 red
## 3 user2 1 25 red
## 4 user2 2 NA NA
## 5 user3 1 32 blue
## 6 user3 2 33 red
# functon that does desired operation
panel_fct <- function(x){
ifelse(is.na(x[2]), x[1], as(NA, class(x)))
}
# use mutate_each to do desired operation
dat_long %>% summarise_each(funs(panel_fct), -panel)
## Source: local data frame [3 x 3]
##
## id age favCol
## 1 user1 NA NA
## 2 user2 25 red
## 3 user3 NA NA
当然,您可以将最终结果合并回原始数据,但对于大多数操作,最好使用长数据。
dat_long %>% summarise_each(funs(panel_fct), -panel) %>% left_join(dat, by = "id")
## Source: local data frame [3 x 7]
##
## id age favCol agePanel1 agePanel2 favColPanel1 favColPanel2
## 1 user1 NA NA 20 21 blue red
## 2 user2 25 red 25 NA red NA
## 3 user3 NA NA 32 33 blue red