【问题标题】:Delete repeated fields in an R data.frame删除 R data.frame 中的重复字段
【发布时间】:2015-09-29 16:39:01
【问题描述】:

我是 R 的新手,我需要你的帮助来做一些我至今无法做到的事情:

我有一个可以包含随机列数的数据框,我需要在数据框的每一列中只保留唯一值,但这必须独立于其他列来完成:

例如,如果有以下数据框:

 Column_A   Column_B    Column_C
    A               1           A1  
    A               2           A2
    B               1           A3
    B               2           A4
    C               3           A5
    C               4           A6

这个的输出,在代码之后必须是:

Column_A    Column_B    Column_C
A               1           A1
B               2           A2
C               3           A3
                4           A4
                            A5
                            A6

我已尝试使用 ds <- unique(ds),但它只会留下所有列之间的唯一关系。

我真的很感激你能给我的任何帮助或指导。

提前致谢。

数据

`> str(df)
'data.frame':   6 obs. of  3 variables:
 $ A: chr  "A" "B" "C" "A" ...
 $ B: num  1 2 1 2 3 4
 $ C: chr  "A1" "A2" "A3" "A4" ...`

循环

`i <- 1`
`while (i < ncol(df)){
+  df[i] <-  lapply(df, function(x) {
+           x[duplicated(x)] <- ''
+           c(x[x!=''], x[x==''])})
+ i <- i+1
+}`

【问题讨论】:

  • 你打算用你想要的输出做什么?我几乎从不需要或想要不规则的数组作为列;特别是对于data.frame,每一列的长度必须相同。您可以用空格或 NA 填充列,但有什么意义呢?
  • 输出将被格式化并用于生成我在 alteryx 模块中使用的 dinamyc 查询。

标签: r alteryx


【解决方案1】:

如果有“因子”列,最好将其转换为character 或将'' 作为factor 列的级别之一。在这里,我首先将factor 列更改为character

 indx <- sapply(df1, is.factor)
 df1[indx] <- lapply(df1[indx], as.character) 

循环使用lapply 的列,将duplicated 元素替换为'',排列元素以使空字符串位于末尾(c(x[x=''],x==''])

 df1[] <-  lapply(df1, function(x) {
           x[duplicated(x)] <- ''
           c(x[x!=''], x[x==''])})
 df1
 #   Column_A Column_B Column_C
 #1        A        1       A1
 #2        B        2       A2
 #3        C        3       A3
 #4                 4       A4
 #5                         A5
 #6                         A6

或者另一种选择是使用match

df1[] <- lapply(df1, function(x) c(x[match(unique(x),x)],
               rep('', length(x)-length(unique(x)))))

注意:使用'' 会将数字列类更改为“字符/因子”类。替换为NA 可能会更好,它也可以使用自定义函数is.na/na.omit/complete.cases 等轻松删除。

数据

 df1 <- structure(list(Column_A = structure(c(1L, 1L, 2L, 2L, 3L, 3L), 
 .Label = c("A", 
 "B", "C"), class = "factor"), Column_B = c(1L, 2L, 1L, 2L, 3L, 
 4L), Column_C = structure(1:6, .Label = c("A1", "A2", "A3", "A4", 
 "A5", "A6"), class = "factor")), .Names = c("Column_A", "Column_B", 
 "Column_C"), row.names = c(NA, -6L), class = "data.frame")

【讨论】:

  • 这样做我得到一些错误:1:在[&lt;-.factor*tmp*,重复(x),值=“”)2:在[&lt;-.factor*tmp*,重复(x ), value = "") : 3: In [&lt;-.data.frame(*tmp*, , value = list(A = c(1L, NA, 2L, NA, :
  • @SergioDonosoSoto 最好将因子列更改为更新后的帖子中的字符。此外,您可以通过在 read.csv/read.table 中使用 stringsAsFactors=FALSE 自动执行此操作
  • 谢谢!它真的救了我。
  • 嗨,我正在查看我的数据,在应用匹配或第一个公式之后,当我在我的列中循环这个公式时,第二个公式获取第一列的数据,我不知道不知道为什么:例如我的column_A(带字母)将替换为A, B, Ccolumn_B(以前有数字)也替换为A, B, C!这将适用于除最后一个之外的 每个 列,对于我正在执行的循环:i &lt;- 1while (i &lt; ncol(df)){ + df[i] &lt;- lapply(df, function(x) { + x[duplicated(x)] &lt;- '' + c(x[x!=''], x[x==''])}) + i &lt;- i + 1 + }
  • @SergioDonosoSoto 如果没有dput 示例,我不确定会发生什么。您能否使用前 6 行的 dput 输出更新帖子。根据您展示的示例,我得到了正确的输出
猜你喜欢
  • 2018-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多