对于在“ Submit.and.module”列中具有“ Separate”值的行,我想在其上方直接插入一行并将数据从某些列移至该新行。
具体来说,我想将“ Submit.help”和“策略”列中的数据移到上面的新行。
现在我的数据如下:
我希望数据看起来像这样:
我该怎么做?
答案 0 :(得分:2)
以为我会加入另一种解决方案参加聚会。
数据
data <- data.frame(Which.mod = c("TMH", "TMH-C", "TMH", "FC", "FC"),
Mod.time = c(1.43, 2.31, 0.67, 2.35, 8.22),
Submit.help = c(NA, "Help", NA, NA, "Submit"),
Strategy = c(NA, "Ratio", NA, NA, "Count"),
Submit.and.module = c(NA, "Separate", NA, NA, "Separate"))
基本R
步骤1:制作一个ID列和一个新的数据框,该框是要分隔的行的子集。
data$id <- 1:nrow(data)
data1 <- subset(data, !is.na(Submit.and.module))
第2步:将适当的列设置为NA并绑定数据帧
data[, c("Submit.help", "Strategy")] <- NA
data1[, c("Which.mod", "Mod.time", "Submit.and.module")] <- NA
第3步:绑定数据帧和顺序。
final <- rbind(data1, data)
final.ordered <- df1[order(df1$id), ]
# Which.mod Mod.time Submit.help Strategy Submit.and.module id
# 1 TMH 1.43 <NA> <NA> <NA> 1
# 2 <NA> NA Help Ratio <NA> 2
# 21 TMH-C 2.31 <NA> <NA> Separate 2
# 3 TMH 0.67 <NA> <NA> <NA> 3
# 4 FC 2.35 <NA> <NA> <NA> 4
# 5 <NA> NA Submit Count <NA> 5
# 51 FC 8.22 <NA> <NA> Separate 5
Tidyverse
又好又简单 跟随。与上述步骤相同,但要尽可能地链接在一起。
library(tidyverse)
dat1 <- data %>% mutate(id = 1:n(), Submit.help = NA, Strategy = NA)
dat2 <- data %>% mutate(id = 1:n()) %>%
filter(!is.na(Submit.and.module)) %>%
mutate(Which.mod = NA, Mod.time = NA, Submit.and.module = NA)
final <- rbind(dat2, dat1) %>% arrange(id)
答案 1 :(得分:1)
这个想法是将要复制的列剪切到一个单独的数据表中,将其添加到原始数据中(最后),并使用名为“ sort”的帮助列将这些行按正确的顺序排序:>
library(data.table)
data <- data.table(Which.mod = c("TMH", "TMH-C", "TMH", "FC", "FC"),
Mod.time = c(1.43, 2.31, 0.67, 2.35, 8.22),
Submit.help = c(NA, "Help", NA, NA, "Submit"),
Strategy = c(NA, "Ratio", NA, NA, "Count"),
Submit.and.module = c(NA, "Separate", NA, NA, "Separate"))
data[, sort := (1:.N) * 10] # add a row sorting value with a gap to fill in inserted rows
# cut columns to be duplicated and "insert" at the end
res <- rbind(data,
data[Submit.and.module == "Separate", .(sort, Submit.help, Strategy)] [, sort := sort - 1],
use.names = TRUE,
fill = TRUE)
# Purge content of moved columns (credits go to @ismiregal - I forgot this initially)
res[Submit.and.module %in% "Separate", c("Submit.help", "Strategy") := NA]
# sort the result accordingly
res <- res[order(sort),]
结果:
res
Which.mod Mod.time Submit.help Strategy Submit.and.module sort
1: TMH 1.43 <NA> <NA> <NA> 10
2: <NA> NA Help Ratio <NA> 19
3: TMH-C 2.31 <NA> <NA> Separate 20
4: TMH 0.67 <NA> <NA> <NA> 30
5: FC 2.35 <NA> <NA> <NA> 40
6: <NA> NA Submit Count <NA> 49
7: FC 8.22 <NA> <NA> Separate 50
答案 2 :(得分:1)
代码很丑陋,但是如果您需要,我会尽力解释它的作用(如果我早上会记得的话)。当然,还有另一种优雅的方法可以做到这一点。但是只是为了庆祝多样性...
dat <- data.frame(
Wich.mod = c("TMH", "TMH-C", "TMH", "FC", "FC"),
Mod.time = c(1.43, 2.31, 0.67, 2.35, 8.22),
Submit.help = c(NA, "Help", NA, NA, "Submit"),
Strategy = c(NA, "Ratio", NA, NA, "Count"),
Submit.and.module = c(NA, "Separate", NA, NA, "Separate"),
stringsAsFactors = F
)
## create new data.frame, filled with NA. The same cols, but extra N("Separate") rows
newdata <- data.frame(matrix(NA, nrow(dat), ncol(dat) + sum(grepl("Separate", dat[, 5]))))
## insert data from dat, leaving empty spaces before "Separate"
newdata[1:nrow(dat) + cumsum(grepl("Separate", dat[, 5])), ] <- dat[1:nrow(dat),]
## give newdata column names from old data
colnames(newdata) <- colnames(dat)
## move Submit.help and Strategy related to "Separate" a row up
newdata[
which(newdata[, 5] == "Separate") - 1, 3:4
] <- newdata[which(newdata[, 5] == "Separate"), 3:4]
## for variables above, replace old values related to "Separate" with NA
newdata[which(newdata[, 5] == "Separate"), 3:4] <- NA
# Wich.mod Mod.time Submit.help Strategy Submit.and.module
# 1 TMH 1.43 NA NA NA
# 2 NA NA Help Ratio NA
# 3 TMH-C 2.31 NA NA Separate
# 4 TMH 0.67 NA NA NA
# 5 FC 2.35 NA NA NA
# 6 NA NA Submit Count NA
# 7 FC 8.22 NA NA Separate
答案 3 :(得分:1)
这是另一个data.table解决方案(看来我太慢了):
library(data.table)
DT <- data.table(stringsAsFactors=FALSE,
Index = seq(5),
Which.mod = c("TMH", "TMH-C", "TMH", "FC", "FC"),
Mod.time = c(1.43, 2.31, 0.67, 2.35, 8.22),
Submit.help = c(NA, "Help", NA, NA, "Submit"),
Strategy = c(NA, "Ratio", NA, NA, "Count"),
Submit.and.module = c(NA, "Separate", NA, NA, "Separate")
)
DT <- rbindlist(list(DT, DT[Submit.and.module %in% "Separate", c("Index", "Submit.help", "Strategy")]), use.names=TRUE, fill=TRUE)
DT[Submit.and.module %in% "Separate", c("Submit.help", "Strategy") := NA]
setorder(DT, Index, Mod.time, na.last=FALSE)
print(DT)
答案 4 :(得分:0)
这是一个tidyverse
解决方案:
library(tidyverse)
nms <- names(df1)
df1 %>%
rowid_to_column %>%
gather(,,-rowid) %>%
filter(!is.na(value)) %>%
mutate(tmp = key %in% c("Which.mod","Mod.time","Submit.and.module")) %>%
spread(key,value) %>%
select_at(nms)
# Which.mod Mod.time Submit.help Strategy Submit.and.module
# 1 TMH 1.43 <NA> <NA> <NA>
# 2 <NA> <NA> Help Ratio <NA>
# 3 TMH-C 2.31 <NA> <NA> Separate
# 4 TMH 0.67 <NA> <NA> <NA>
# 5 FC 2.35 <NA> <NA> <NA>
# 6 <NA> <NA> Submit Count <NA>
# 7 FC 8.22 <NA> <NA> Separate
数据
df1 <- data.frame(
Which.mod = c("TMH", "TMH-C", "TMH", "FC", "FC"),
Mod.time = c(1.43, 2.31, 0.67, 2.35, 8.22),
Submit.help = c(NA, "Help", NA, NA, "Submit"),
Strategy = c(NA, "Ratio", NA, NA, "Count"),
Submit.and.module = c(NA, "Separate", NA, NA, "Separate"),
stringsAsFactors = FALSE
)