假设我有一个由"/"
分割并已放入数据帧的文件路径向量。这些文件路径具有不同的长度,但是到了一天结束时,我希望所有基本名称都在同一列中排列。我在下面提供了我的意思和所需输出的示例。
library(tidyverse)
dat <- tibble(
V1 = rep("run1", 5),
V2 = rep("ox", 5),
V3 = c("performance.csv", "analysis", "analysis", "performance.csv", "analysis"),
V4 = c("", "rod1", "rod2", "rod3", "performance.csv"),
V5 = c("", "performance.csv", "performance.csv", "performance.csv", "")
)
dat
#> # A tibble: 5 x 5
#> V1 V2 V3 V4 V5
#> <chr> <chr> <chr> <chr> <chr>
#> 1 run1 ox performance.csv "" ""
#> 2 run1 ox analysis rod1 performance.csv
#> 3 run1 ox analysis rod2 performance.csv
#> 4 run1 ox performance.csv rod3 performance.csv
#> 5 run1 ox analysis performance.csv ""
output <- tibble(
V1 = rep("run1", 5),
V2 = rep("ox", 5),
V3 = c("", "analysis", "analysis", "", "analysis"),
V4 = c("", "rod1", "rod1", "rod2", ""),
V5 = c("performance.csv", "performance.csv", "performance.csv", "performance.csv", "performance.csv")
)
output
#> # A tibble: 5 x 5
#> V1 V2 V3 V4 V5
#> <chr> <chr> <chr> <chr> <chr>
#> 1 run1 ox "" "" performance.csv
#> 2 run1 ox analysis rod1 performance.csv
#> 3 run1 ox analysis rod1 performance.csv
#> 4 run1 ox "" rod2 performance.csv
#> 5 run1 ox analysis "" performance.csv
我的想法是求助于for循环,在该循环中,我检查一列是否包含基本名称,如果包含,则将其替换为""
并将其移至最后一列。我在形成这种逻辑时遇到困难,并且知道必须有一种更好的方法来利用tidyverse。
答案 0 :(得分:6)
创建一个函数rearrange
,该函数重新排列行,将基名放在最后,如果它的末尾还没有,则将其原始位置清空。我们假定任何带点的条目都是基本名称。然后将rearrange
应用于每一行。
rearrange <- function(x) {
i <- grep(".", x, fixed = TRUE)[1]
x[length(x)] <- x[i]
if (i < length(x)) x[i] <- ""
x
}
as_tibble(t(apply(dat, 1, rearrange)))
给予:
# A tibble: 5 x 5
V1 V2 V3 V4 V5
<chr> <chr> <chr> <chr> <chr>
1 run1 ox "" "" performance.csv
2 run1 ox analysis rod1 performance.csv
3 run1 ox analysis rod2 performance.csv
4 run1 ox "" rod3 performance.csv
5 run1 ox analysis "" performance.csv
答案 1 :(得分:1)
这是一种tidyverse
的方式-
dat %>%
rownames_to_column("id") %>%
gather(key, variable, -id) %>%
group_by(id) %>%
mutate(
variable = case_when(
key == "V5" ~ tail(grep(".csv", x = variable, value = T), 1),
key != "V5" & grepl(".csv", x = variable) ~ "",
TRUE ~ variable
)
) %>%
ungroup() %>%
spread(key, variable)
# A tibble: 5 x 6
id V1 V2 V3 V4 V5
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 run1 ox "" "" performance.csv
2 2 run1 ox analysis rod1 performance.csv
3 3 run1 ox analysis rod2 performance.csv
4 4 run1 ox "" rod3 performance.csv
5 5 run1 ox analysis "" performance.csv
答案 2 :(得分:1)
一个base R
使用max.col
的选项。获取数据集的子集的列索引(第3列至第5列),其中.
作为元素,cbind
与行索引(seq_len(nrow(dat))
),根据以下内容从数据集中提取元素:这些索引并将其分配给“ V5”。然后根据逻辑矩阵(do.call(cbind, .
)的TRUE值将第三列和第四列更改为空白(""
)
dat <- as.data.frame(dat)
lst1 <- lapply(dat[3:5], grepl, pattern = '\\.')
ij <- cbind(seq_len(nrow(dat)), max.col(do.call(cbind, lst1), 'first'))
dat$V5 <- dat[3:5][ij]
dat[3:4][do.call(cbind, lst1[1:2])] <- ""
dat
# V1 V2 V3 V4 V5
#1 run1 ox performance.csv
#2 run1 ox analysis rod1 performance.csv
#3 run1 ox analysis rod2 performance.csv
#4 run1 ox rod3 performance.csv
#5 run1 ox analysis performance.csv
或将tidyverse
与coalesce
一起使用。在这里,我们将select
列“ V3”到“ V5”遍历列(map
),replace
将.csv
以外的元素NA
,coalesce
将其绑定到单个列,将该列与原始数据集的子集列绑定,并将replace
的第.
列为空白的第{3}至第4列(""
)
library(tidyverse)
dat %>%
select(V3:V5) %>%
map_df(~ replace(.x, str_detect(.x, "\\.csv", negate = TRUE), NA)) %>%
transmute(V5 = coalesce(!!! .)) %>%
bind_cols(dat %>%
select(-V5), .) %>%
mutate_at(vars(3:4), list(~ replace(., str_detect(., "\\."), '')))
# A tibble: 5 x 5
# V1 V2 V3 V4 V5
# <chr> <chr> <chr> <chr> <chr>
#1 run1 ox "" "" performance.csv
#2 run1 ox analysis rod1 performance.csv
#3 run1 ox analysis rod2 performance.csv
#4 run1 ox "" rod3 performance.csv
#5 run1 ox analysis "" performance.csv