【问题标题】:Replace non-zero values of a dataframe替换数据帧的非零值
【发布时间】:2019-04-05 10:16:39
【问题描述】:

我有一个如下示例数据的数据框。

> dput(df)
structure(list(BranchCode = structure(c(9L, 3L, 2L, 1L, 10L, 
6L, 8L, 11L, 4L, 5L, 7L), .Label = c("BU", "CA", "GT", "IN", 
"LM", "OX", "QC", "SR", "TD", "WG", "YV"), class = "factor"), 
    Requirement = c(0L, 5L, 12L, 1L, 0L, 0L, 6L, 0L, 3L, 10L, 
    0L), Availabile = c(3L, 3L, 0L, 7L, 0L, 8L, 0L, 0L, 7L, 3L, 
    6L), Alternative = c(9L, 0L, 0L, 0L, 10L, 2L, 3L, 8L, 0L, 
    0L, 5L), Complex = c(3L, 2L, 7L, 5L, 0L, 0L, 7L, 2L, 0L, 
    6L, 3L), Level1 = c(0L, 6L, 0L, 0L, 6L, 0L, 9L, 0L, 0L, 0L, 
    0L), Level2 = c(4L, 0L, 0L, 8L, 1L, 6L, 10L, 18L, 0L, 3L, 
    5L)), .Names = c("BranchCode", "Requirement", "Availabile", 
"Alternative", "Complex", "Level1", "Level2"), class = "data.frame", row.names = c(NA, 
-11L))

我需要用数字 1 替换所有非零值。我可以通过两种方式做到这一点。

  1. 一次使用一列进行替换,如下所示。然后我每次都必须更改列名。

    df$Requirement[df$Requirement != 0] <- 1

  2. 我可以编写一个基本的for 循环并根据条件进行替换,通过索引。

但这两个过程对我来说都需要时间,因为每次列或行都会增加(有时是 200 列和 20000 行)。所以我想一次在整个数据帧上做这个过程。就像不逐列替换或按数据帧上的 for 循环索引一样,我需要用数字 1 替换任何非零数值的地方。如下所示(但不起作用)。

df[which(df[2:7] != 0)] <- 1

最终的数据框如下所示。

> df
   BranchCode Requirement Availabile Alternative Complex Level1 Level2
1          TD           0          1           1       1      0      1
2          GT           1          1           0       1      1      0
3          CA           1          0           0       1      0      0
4          BU           1          1           0       1      0      1
5          WG           0          0           1       0      1      1
6          OX           0          1           1       0      0      1
7          SR           1          0           1       1      1      1
8          YV           0          0           1       1      0      1
9          IN           1          1           0       0      0      0
10         LM           1          1           0       1      0      1
11         QC           0          1           1       1      0      1

解决方案或建议会很棒。

【问题讨论】:

  • df[df != 0] &lt;- 1
  • @sotos,感谢您花时间研究它。您的建议做得很好,但它使所有其他非数字列变成了NA。除了从原始 df 复制相应的列之外,我还需要做任何额外的过程吗?

标签: r dataframe


【解决方案1】:

你可以的

df[-1] <- as.integer(df[-1] != 0)
df
#   BranchCode Requirement Availabile Alternative Complex Level1 Level2
#1          TD           0          1           1       1      0      1
#2          GT           1          1           0       1      1      0
#3          CA           1          0           0       1      0      0
#4          BU           0          1           0       1      0      1
#5          WG           0          0           1       0      1      0
#6          OX           0          1           1       0      0      1
#7          SR           1          0           1       1      1      1
#8          YV           0          0           1       1      0      1
#9          IN           1          1           0       0      0      0
#10         LM           1          1           0       1      0      1
#11         QC           0          1           1       1      0      1

如果您有多个非数字列并且需要先找到它们的位置,您可以这样做

numeric_cols <- vapply(df, is.numeric, logical(1))
df[numeric_cols] <- as.integer(df[numeric_cols] != 0)
df

【讨论】:

  • 哇,简直不敢相信一行代码就解决了我的问题。它为我创造了奇迹。非常感谢。
【解决方案2】:
df1[-1] <- + sapply(df1[-1], as.logical)

#   BranchCode Requirement Availabile Alternative Complex Level1 Level2
#1          TD           0          1           1       1      0      1
#2          GT           1          1           0       1      1      0
#3          CA           1          0           0       1      0      0
#4          BU           1          1           0       1      0      1
#5          WG           0          0           1       0      1      1
#6          OX           0          1           1       0      0      1
#7          SR           1          0           1       1      1      1
#8          YV           0          0           1       1      0      1
#9          IN           1          1           0       0      0      0
#10         LM           1          1           0       1      0      1
#11         QC           0          1           1       1      0      1

  • 使用 as.logical 时,每 0 得到 FALSE (0) 每 n &gt;= 1 得到 TRUE (1)
  • 添加 + 会将类型转换为整数。

【讨论】:

  • 绝妙的解决方案。感谢您的时间和解决方案。
【解决方案3】:

只是对之前答案的补充。

df[-1] <- as.numeric(df[-1] != 0)
df[-1] <- as.numeric(df[-1] != 0, as.logical)
df[-1] <- as.numeric(as.logical(df[-1] != 0))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-19
    • 2018-01-23
    • 2015-08-24
    • 1970-01-01
    • 2018-01-05
    • 2016-01-20
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多