如何在R语言中为序列对应位置补充缺失值?
问题描述
我有如下格式的DataFrame:
dat <- data.frame(matrix(nrow = 10, ncol = 4)) dat$X1 <- seq(1,10) dat$X2 <- c(1,1,1,1,2,2,2,2,3,3) dat$X3 <- c(1) dat$X4 <- c("c(2,3,4)","c(1,2,4)","c(1,2,3,4)","c(1,2,3)","c(1,2,3,4)", "c(1,2,3,4)","c(2,3,4)","c(1,2,3)","c(1,2,3,4)","c(1,2,3,4)") colnames(dat) <- c("Subject","Session","other","option")
我尝试用tidyr包处理:
library(tidyr) dat <- separate(dat, option, sep = ",", into = paste0("option.", 1:4)) colnames(dat) <- c("Subject","Session","other","pk1","pk2","pk3","pk4") dat$pk1 <- gsub("c", "", dat$pk1) dat$pk1 <- gsub("[()]", "", dat$pk1) dat$pk3 <- gsub("[()]", "", dat$pk3)
但我需要得到如下格式的结果:
dat <- data.frame(matrix(nrow = 10, ncol = 4)) dat$X1 <- seq(1,10) dat$X2 <- c(1,1,1,1,2,2,2,2,3,3) dat$X3 <- c(1) dat$X4 <- c("c(NA,2,3,4)","c(1,2,NA,4)","c(1,2,3,4)","c(1,2,3,NA)","c(1,2,3,4)", "c(1,2,3,4)","c(NA,2,3,4)","c(1,2,3,NA)","c(1,2,3,4)","c(1,2,3,4)") colnames(dat) <- c("Subject","Session","other","option") dat <- separate(dat, option, sep = ",", into = paste0("option.", 1:4)) colnames(dat) <- c("Subject","Session","other","pk1","pk2","pk3","pk4") dat$pk1 <- gsub("c", "", dat$pk1) dat$pk1 <- gsub("[()]", "", dat$pk1) dat$pk4 <- gsub("[()]", "", dat$pk4) dat # Subject Session other pk1 pk2 pk3 pk4 # 1 1 1 1 NA 2 3 4 # 2 2 1 1 1 2 NA 4 # 3 3 1 1 1 2 3 4 # 4 4 1 1 1 2 3 NA # 5 5 2 1 1 2 3 4 # 6 6 2 1 1 2 3 4 # 7 7 2 1 NA 2 3 4 # 8 8 2 1 1 2 3 NA # 9 9 3 1 1 2 3 4 # 10 10 3 1 1 2 3 4
请问该如何为序列添加对应位置的缺失值?
解决方案
提供两种可行的处理方式,都能得到目标结果:
方法一:解析向量后补全NA
先把option列的字符串转换成实际数值向量,再将每个向量补全到4个元素,缺失的位置填充NA,最后拆分到对应列:
library(dplyr) library(tidyr) # 原始数据 dat <- data.frame(matrix(nrow = 10, ncol = 4)) dat$X1 <- seq(1,10) dat$X2 <- c(1,1,1,1,2,2,2,2,3,3) dat$X3 <- c(1) dat$X4 <- c("c(2,3,4)","c(1,2,4)","c(1,2,3,4)","c(1,2,3)","c(1,2,3,4)", "c(1,2,3,4)","c(2,3,4)","c(1,2,3)","c(1,2,3,4)","c(1,2,3,4)") colnames(dat) <- c("Subject","Session","other","option") # 处理流程 dat_processed <- dat %>% # 将字符串格式的向量解析为实际R向量 mutate(option = lapply(option, function(x) eval(parse(text = x)))) %>% # 补全每个向量到4个元素,对应位置缺失则填NA mutate(option = lapply(option, function(x) { full_vec <- rep(NA, 4) full_vec[x] <- x full_vec })) %>% # 将向量拆分为单独的列 unnest_wider(option, names_sep = "") %>% # 重命名为目标列名 rename(pk1 = option1, pk2 = option2, pk3 = option3, pk4 = option4) # 查看结果 dat_processed
方法二:纯字符串处理补全NA
如果担心eval解析字符串的风险,可以直接通过字符串操作提取数字,对比完整序列后补全NA:
library(tidyr) library(stringr) library(dplyr) # 原始数据 dat <- data.frame(matrix(nrow = 10, ncol = 4)) dat$X1 <- seq(1,10) dat$X2 <- c(1,1,1,1,2,2,2,2,3,3) dat$X3 <- c(1) dat$X4 <- c("c(2,3,4)","c(1,2,4)","c(1,2,3,4)","c(1,2,3)","c(1,2,3,4)", "c(1,2,3,4)","c(2,3,4)","c(1,2,3)","c(1,2,3,4)","c(1,2,3,4)") colnames(dat) <- c("Subject","Session","other","option") # 处理流程 dat_processed <- dat %>% # 提取每个option中的数字 mutate(nums = str_extract_all(option, "\\d+")) %>% # 对比完整的1-4序列,缺失位置填NA mutate(option = lapply(nums, function(x) { full_seq <- 1:4 ifelse(full_seq %in% as.integer(x), full_seq, NA) })) %>% # 拆分向量为单独列并重命名 unnest_wider(option, names_sep = "") %>% rename(pk1 = option1, pk2 = option2, pk3 = option3, pk4 = option4) %>% # 移除中间临时列 select(-nums) # 查看结果 dat_processed
内容的提问来源于Stack Exchange,提问作者jc2525
相关产品推荐
相关产品推荐

