将部分行数据用于 R 中的新列

Use part of row data for new columns in R

我有一个非常大的 df,其中有一列包含每行数据的文件目录。

示例:D:Mouse_2174/experiment/13/trialsummary.txt.1

我想创建 2 个新列,一个只有鼠标 ID (2174),一个有会话号 (13)。根据行会有不同的ID和会话号。

我已经按照这里的建议使用了 sub (match part of names in data.frame to new column),但只能让主题栏显示“D:Mouse_2174” 我已经添加了一个额外的行并且可以得到它下降到“D:Mous2174”

有没有办法把_之前和/之后的字符都去掉,得到鼠标ID? 对于会话号,我不太确定如何处理目录名称中的多个 /。

percent_correct_list$mouse_id <- sub("/.+", "", percent_correct_list$rn)
#gives me D:Mouse_2174
percent_correct_list$mouse_id <- sub("+._", "", percent_correct_list$mouse_id)
#gives me D:Mous2174

以下是目录的示例代码:

df <- data.frame(
             rn = c("D:Mouse_2174/iti_intervals/9/trialsummary.txt.1",
                    "D:Mouse_2181/iti_intervals/33/trialsummary.txt.1",
                    "D:Mouse_2183/iti_intervals/107/trialsummary.txt.2",
                    "D:Mouse_2185/iti_intervals/87/trialsummary.txt.1")
)

我想要的:

rn id session
D:.. 2174 9
D:.. 2181 33
D:.. 2183 107
D:.. 2185 87

也许在这个过程的早期也有一些方法可以做到这一点(比如当我使用 lapply 将所有数据导入 df 时 - 但这也很好)

这里有一个有点 long-winded 的解决方案,使用 tidyr::separate。也许还有更多 concise/elegant.

它假定 rn 的所有值都采用相同的格式。

library(dplyr)
library(tidyr)

new_df <- df %>% 
  # separate on / into 4 new columns
  separate(rn, into = c(paste0("item", 1:4)), sep = "/", remove = FALSE) %>%
  # remove unwanted columns
  select(-item2, -item4) %>% 
  # separate again on _ into 2 new columns
  separate(item1, sep = "_", into = c("prefix", "id")) %>%
  # retain and rename desired columns 
  select(rn, id, session = item3)

结果:

                                                 rn   id session
1   D:Mouse_2174/iti_intervals/9/trialsummary.txt.1 2174       9
2  D:Mouse_2181/iti_intervals/33/trialsummary.txt.1 2181      33
3 D:Mouse_2183/iti_intervals/107/trialsummary.txt.2 2183     107
4  D:Mouse_2185/iti_intervals/87/trialsummary.txt.1 2185      87

这肯定不是一个优雅的解决方案。仅当您的 ID 和 Session 始终为数字时才有效...

df <- data.frame(
            rn = c("D:Mouse_2174/iti_intervals/9/trialsummary.txt.1",
                   "D:Mouse_2181/iti_intervals/33/trialsummary.txt.1",
                   "D:Mouse_2183/iti_intervals/107/trialsummary.txt.2",
                   "D:Mouse_2185/iti_intervals/87/trialsummary.txt.1")) %>%
            # Extract all numeric values from the string
            mutate(allnums = regmatches(rn, gregexpr("+[[:digit:]]+", rn)))%>%
            # Separate them
            separate(allnums, into = c("id", "session", "idk"), sep = "\,") %>%
            # Extract them individually
            mutate(id = as.numeric(regmatches(id, gregexpr("+[[:digit:]]+", id,))),
                   session = as.numeric(regmatches(session, gregexpr("+[[:digit:]]+", session)))) %>%
            select(-idk)

输出:

1  D:Mouse_2174/iti_intervals/9/trialsummary.txt.1   2174       9
2  D:Mouse_2181/iti_intervals/33/trialsummary.txt.1  2181      33
3  D:Mouse_2183/iti_intervals/107/trialsummary.txt.2 2183     107
4  D:Mouse_2185/iti_intervals/87/trialsummary.txt.1  2185      87