簡體   English   中英

使用所選列中的所有值的最大值有條件地更新某些列(data.table,r)

[英]Update some columns conditionally with max value for all values in chosen columns (data.table, r)

我有900,000 x 500類型的數據集,但下面顯示了適合該問題的玩具數據集。

library(data.table)
df1 <- data.table(x = c(1,2,4,0), y = c(0,0,10,15), z = c(1,1,1,0))

我想做以下事情:

  1. 對於y和z列
  2. 選擇行的值= 0
  3. 用max + 1替換它們,其中max是在整個列上計算的

我是data.table的新手。 在stackoverflow上查看問題的示例,我找不到類似的問題,除了這個: 如何替換表*中的NA值用於所選列*? data.frame,data.table

我自己的嘗試如下,但這不起作用:

for (col in c("x", "y")) df1[(get(col)) == 0, (col) := max(col) + 1)

顯然,我還沒有習慣於data.table ,所以我現在正撞在牆上......

如果有人能提供除data.table之外的dplyr解決方案,我會很感激。

我們可以使用set並將值為0的行分配給該列的max +1。

 for(j in c("y", "z")){
    set(df1, i= which(!df1[[j]]), j=j, value= max(df1[[j]])+1)
 }

df1
#   x  y z
#1: 1 16 1
#2: 2 16 1
#3: 4 10 1
#4: 0 15 2

注意: set方法非常有效,因為避免了[.data.table的開銷


或者,效率較低的方法是在.SDcols指定感興趣的列,循環遍歷列( lapply(.. ),根據邏輯索引replace值,並將輸出分配( := )回列。

df1[, c('y', 'z') := lapply(.SD, function(x) 
         replace(x, !x, max(x)+1)), .SDcols= y:z]

dplyr版本非常簡單(我認為)

> library(dplyr)
# indented for clarity
> mutate(df1, 
    y= ifelse(y>0, y, max(y)+1), 
    z= ifelse(z>0, z, max(z)+1))

  x  y z
1 1 16 1
2 2 16 1
3 4 10 1
4 0 15 2

編輯正如David Arenburg在評論中指出的那樣,這對於玩具示例很有幫助,但對於提到500列的數據卻沒有。 他建議類似於:

df1 %>% mutate_each(funs(ifelse(. > 0, ., max(.) + 1)), -1)

其中-1指定除第一列之外的所有列

作為替代方案, ifelse(test, yes, no)可能有用

沿線

library(data.table)
dt <- data.table(x = c(1,2,4,0), y = c(0,0,10,15), z = c(1,1,1,0))

print(dt)

dt[, y := ifelse(!y, max(y) + 1, y)]

print(dt)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM