使用模式重新格式化数据

发布于 2024-12-04 07:20:00 字数 767 浏览 0 评论 0原文

我有一个包含数字和字母混合的大型数据集。只是一个小例子:

sex <- c("M", "F", "F", "M", "M")
 ind <- c("I1", "I2", "I3", "I4", "C")
M1 <- c("ab", "bb", "ac", "ad", "dd")
M2 <- c(12, 22, 23, 24, 25)
M3 <- c("AT", "AG", "AC", "GG", "TC")
 M4 <- c(22, 23, 24, 14, 24)
mydf <- data.frame(sex, ind, M1, M2, M3, M4)
mydf
  sex ind M1 M2 M3 M4
1   M  I1 ab 12 AT 22
2   F  I2 bb 22 AG 23
3   F  I3 ac 23 AC 24
4   M  I4 ad 24 GG 14
5   M   C dd 25 TC 24

我想在 M1......Mn 列(文件末尾)中的两个字符之间引入“/”标记,以便生成的数据框看起来像:

       sex ind M1 M2 M3 M4
    1   M  I1 a/b 1/2 A/T 2/2
    2   F  I2 b/b 2/2 A/G 2/3
    3   F  I3 a/c 2/3  A/C 2/4
    4   M  I4 a/d 2/4 G/G 1/4
    5   M   C d/d 2/5 T/C 2/4

抱歉,我不知道如何继续。 ..感谢您的帮助...

I have a large dataset with mix of number and alphabets. Just an small example:

sex <- c("M", "F", "F", "M", "M")
 ind <- c("I1", "I2", "I3", "I4", "C")
M1 <- c("ab", "bb", "ac", "ad", "dd")
M2 <- c(12, 22, 23, 24, 25)
M3 <- c("AT", "AG", "AC", "GG", "TC")
 M4 <- c(22, 23, 24, 14, 24)
mydf <- data.frame(sex, ind, M1, M2, M3, M4)
mydf
  sex ind M1 M2 M3 M4
1   M  I1 ab 12 AT 22
2   F  I2 bb 22 AG 23
3   F  I3 ac 23 AC 24
4   M  I4 ad 24 GG 14
5   M   C dd 25 TC 24

I want to introduce a "/" marks between two characters in columns M1......Mn (end of the file) so that the resulting data frame look like:

       sex ind M1 M2 M3 M4
    1   M  I1 a/b 1/2 A/T 2/2
    2   F  I2 b/b 2/2 A/G 2/3
    3   F  I3 a/c 2/3  A/C 2/4
    4   M  I4 a/d 2/4 G/G 1/4
    5   M   C d/d 2/5 T/C 2/4

Sorry I was clueless how to proceed ...your help appreciated ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谈场末日恋爱 2024-12-11 07:20:00

一班轮:

> data.frame(lapply(mydf, function(x) sub("(.)(.)", "\\1/\\2", x)))
  sex ind  M1  M2  M3  M4
1   M I/1 a/b 1/2 A/T 2/2
2   F I/2 b/b 2/2 A/G 2/3
3   F I/3 a/c 2/3 A/C 2/4
4   M I/4 a/d 2/4 G/G 1/4
5   M   C d/d 2/5 T/C 2/4

One liner:

> data.frame(lapply(mydf, function(x) sub("(.)(.)", "\\1/\\2", x)))
  sex ind  M1  M2  M3  M4
1   M I/1 a/b 1/2 A/T 2/2
2   F I/2 b/b 2/2 A/G 2/3
3   F I/3 a/c 2/3 A/C 2/4
4   M I/4 a/d 2/4 G/G 1/4
5   M   C d/d 2/5 T/C 2/4
染年凉城似染瑾 2024-12-11 07:20:00

R 的所有神秘功能为您提供了以下功能:

  • splitInsert 使用 strsplit 在每个字母处拆分一列,并使用 paste 将其重新组合。它被包装在 sapply 中以向量化该函数。
  • 然后,我使用 lapply 在 data.frame 的第 3:6 列上应用 splitInsert,并使用 data.frame 将其与两列合并你不想修改的。
  • 请注意,splitInsert 是完全通用的 - 它适用于任何长度的文本字符串,并且您可以使用选择的任何新字符来重新组合拆分元素。

代码:

splitInsert <- function(x, split="", new="/"){
  sapply(x, function(y)
    paste(
      strsplit(as.character(y), split=split)[[1]], 
      collapse=new)
         )
}

data.frame(mydf[, 1:2], lapply(mydf[, 3:ncol(mydf)], splitInsert))

结果:

  sex ind  M1  M2  M3  M4
1   M  I1 a/b 1/2 A/T 2/2
2   F  I2 b/b 2/2 A/G 2/3
3   F  I3 a/c 2/3 A/C 2/4
4   M  I4 a/d 2/4 G/G 1/4
5   M   C d/d 2/5 T/C 2/4

All of the cryptic power of R gives you this:

  • splitInsert splits a column at each letter using strsplit and recombines it with paste. This is wrapped in sapply to vectorise the function.
  • I then use lapply to apply splitInsert over columns 3:6 of your data.frame, and data.frame to combine it with the two columns that you don't want modified.
  • Note that splitInsert is fully general - it will work for text strings of any length, and you can use any new character of choice to recombine the split elements.

The code:

splitInsert <- function(x, split="", new="/"){
  sapply(x, function(y)
    paste(
      strsplit(as.character(y), split=split)[[1]], 
      collapse=new)
         )
}

data.frame(mydf[, 1:2], lapply(mydf[, 3:ncol(mydf)], splitInsert))

The results:

  sex ind  M1  M2  M3  M4
1   M  I1 a/b 1/2 A/T 2/2
2   F  I2 b/b 2/2 A/G 2/3
3   F  I3 a/c 2/3 A/C 2/4
4   M  I4 a/d 2/4 G/G 1/4
5   M   C d/d 2/5 T/C 2/4
小姐丶请自重 2024-12-11 07:20:00

这似乎有效。

m1 <- substr(mydf$M1, start=1, stop=1)
m2 <- substr(mydf$M1, start=2, stop=2)
paste(m1, m2, sep="/")

输出

[1] "a/b" "b/b" "a/c" "a/d" "d/d"

This seems to work.

m1 <- substr(mydf$M1, start=1, stop=1)
m2 <- substr(mydf$M1, start=2, stop=2)
paste(m1, m2, sep="/")

Output

[1] "a/b" "b/b" "a/c" "a/d" "d/d"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文