【问题标题】:Replacing row elements with top and bottom elements用顶部和底部元素替换行元素
【发布时间】:2014-03-20 14:46:14
【问题描述】:

我有一个数据框如下:

未排序的数据:

id  V1  V2  V3  V4  V5  V6  V7  V8  V9  V10
M1  SM1 137 137 +   SM1 168 255 +   xxl 31
M2  SM1 3026005 3026005 -   SM1 3025051 3026062 +   xmu 0
M3  SM1 308128  308128  -   SM1 306713  308597  -   ucl 0
M4  SM1 3027792 3027792 -   SM1 3026280 3028359 +   oml 0
M5  SM1 308129  308129  -   SM1 306713  308597  -   uul 0
M6  SM1 3029695 3029695 -   SM1 3028946 3029864 +   oma 0
M7  SM1 3029738 3029738 -   SM1 3028946 3029864 +   oma 0
M8  SM1 3030415 3030415 +   SM1 3029860 3030682 +   omu 0
M9  SM1 3057386 3057386 -   SM1 3056910 3057822 -   ucle    0
M10 SM1 3069715 3069715 +   SM1 3069459 3069567 +   ohm 148
M11 SM1 3097751 3097751 -   SM1 3096951 3097860 -   umn 0
M12 SM1 3098025 3098025 +   SM1 3098110 3099157 +   icy 85
M14 SM1 3099816 3099816 -   SM1 3100255 3100552 -   occl    439
M15 SMP 3100015 3100015 -   SMP 3100255 3100552 -   occl    240
M16 SMP 3103300 3103300 +   SMP 3104483 3106040 +   abl 183
M17 SMP 3116858 3116858 -   SMP 3115395 3116193 -   zyc 665
M18 SMP 3121053 3121053 -   SMP 3120207 3121845 -   umq 0
M19 SMP 3121957 3121957 +   SMP 3120207 3121845 -   umq 112

数据按以下顺序排序:data$V8,data$V7,data$V1,以便进行有效分析。

排序后的数据:

id  V1  V2  V3  V4  V5  V6  V7  V8  V9  V10
M3  SM1 308128  308128  -   SM1 306713  308597  -   ucl 0
M5  SM1 308129  308129  -   SM1 306713  308597  -   uul 0
M9  SM1 3057386 3057386 -   SM1 3056910 3057822 -   ucle    0
M11 SM1 3097751 3097751 -   SM1 3096951 3097860 -   umn 0
M14 SM1 3099816 3099816 -   SM1 3100255 3100552 -   occl    439
M15 SMP 3100015 3100015 -   SMP 3100255 3100552 -   occl    240
M17 SMP 3116858 3116858 -   SMP 3115395 3116193 -   zyc 665
M18 SMP 3121053 3121053 -   SMP 3120207 3121845 -   umq 0
M19 SMP 3121957 3121957 +   SMP 3120207 3121845 -   umq 112
M1  SM1 137 137 +   SM1 168 255 +   xxl 31
M2  SM1 3026005 3026005 -   SM1 3025051 3026062 +   xmu 0
M4  SM1 3027792 3027792 -   SM1 3026280 3028359 +   oml 0
M6  SM1 3029695 3029695 -   SM1 3028946 3029864 +   oma 0
M7  SM1 3029738 3029738 -   SM1 3028946 3029864 +   oma 0
M8  SM1 3030415 3030415 +   SM1 3029860 3030682 +   omu 0
M10 SM1 3069715 3069715 +   SM1 3069459 3069567 +   ohm 148
M12 SM1 3098025 3098025 +   SM1 3098110 3099157 +   icy 85
M16 SMP 3103300 3103300 +   SMP 3104483 3106040 +   abl 183

我的目标是对排序后的数据执行以下操作:

  1. 如果 data$V10 > 0 & data$V1 == data$V5 & data$V4 == data$V8,则
  2. 将 V9 列的行内容替换为“Beween_TopRowElement-BottomRowElement” (如果 TopRowElement 和 BottomRowElement 与第 v9 列的行中的元素不同)

id M15 且位于 col V9 中的示例“occl”大于 0,因此将替换为“Between_umn_zyc”, 由于 TopRowElement 与 occl 同名,所以使用下一个顶部元素。

我还需要注意特定元素上方或下方没有行的情况。

我编写R代码的尝试如下:

data <- read.delim("data.dat", header=TRUE)
data <- data[order(data$V8, data$V7, data$V1)]
for (i in data.sorted){
  if (data$V10 > 0 & data$V1 == data$V5 & data$V4 == data$V8){
      if (i!=i-1 |  i!=i+1){
        data$V9 =  data["Between_",i-1,"_", i+1]
        data$V1 == data$V5
      }
  }

}
write.table(data, "results.xls", "sep=\t")

M15 的预期输出:

M15 SMP 3100015 3100015 -   SMP 3100255 3100552 -   Between_umn_zyc 240

有人可以帮助改善我糟糕的尝试吗?谢谢

【问题讨论】:

  • 这是什么Beween_TopRowElement、BottomRowElement、TopRowElement、BottomRowElement、Between_umn_zyc 的东西?
  • 澄清一下:Between_umn_zyc 的意思是:Between 是一个描述性的字符串。 umn 是元素的名称。zyc - 是元素的名称。所以,Between_umn_zyc 描述了 M15 在 umn 和 zyc 之间的事实

标签: r


【解决方案1】:

我认为你在排序中漏掉了一个逗号:

data <- data[order(data$V8, data$V7, data$V1) , ]

如果我理解您的问题,您需要为 V9 的每个元素找到 V9 的前一个 不同 值。这应该给你这个价值:

V9 <- data$V9
sameAsPredecessor <- V9[-length(V9)] == V9[-1]
indexOfDifferent <- cumsum(!sameAsPredecessor)
predecessor <- V9[c(NA, indexOfDifferent)]

我在开头添加NA,作为处理边缘情况的一种方式

你可以类似地得到另一个方向的界限:

V9 <- rev(data$V9)
sameAsPredecessor <- V9[-length(V9)] == V9[-1]
indexOfDifferent <- cumsum(!sameAsPredecessor)
follower <- rev(V9[c(NA, indexOfDifferent)])

所以您现在有两个向量 predecessor 和 follower,您可以将它们插入到相关行中 - 类似于:

ind <- data$V10 > 0 & data$V1 == data$V5 & data$V4 == data$V8
data$V9[ind] <- sprintf("Between_%s_%s", predecessor[ind], follower[ind])

而且你不应该需要任何循环

【讨论】:

  • 非常感谢 Kevin 提供的代码。不幸的是,最终输出中生成了 NA:警告消息:In [&lt;-.factor(*tmp*, ind, value = c(472L, 472L, 472L, 472L, : invalid factor level, NA generated
  • 这是 Gavin 而不是 Kevin。如果您将 data$V9 的类型更改为 data$V9 &lt;- as.character(dat$V9) 的字符,那么您将不会仅限于最初在该列中的值。
  • 为你的名字 Gavin 道歉。很高兴让您知道这解决了 NAN 问题。如果满足这些条件:data$V10 > 0 & data$V1 == data$V5 & data$V4 == data$V8,那么是几个场景。 (1)。在直接边界值(上方和下方)与 V9 值不同的任何情况下,这都适用:“Between_above_below”,(2)。否则,如果立即边界值(上方和下方)与 V9 值相同,则代码向上/向下查找与 V9 不同的下一个边界值,最后应用“Between_above_below”
  • 上述评论的补充:不幸的是,输出中的“Between_Top_Bottom”不正确。我确定这是由于我一开始的解释不佳,因此我添加了上述评论。谢谢
  • 好的,使用indexOfReplacement &lt;- match(V9, V9)-1,因为这将为每一行找到前面不同V9的行号,即使它不是它的直接邻居。假设您的 V9 值出现在实际上不重复的运行中。您需要具体说明您想要实现的目标 - 我们正在做大量的猜测工作,所以如果这不能回答您的问题,请尝试准确提取 V9 的要求 - 我们没有真的需要考虑其他列的条件。
猜你喜欢
  • 1970-01-01
  • 2019-09-25
  • 2010-11-26
  • 2021-03-30
  • 2012-07-23
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多