簡體   English   中英

如何將數據框中的 0 值替換為 R 中非零行最小值的 0.5 倍(0.5*min)

[英]How to replace 0 values in data frame with 0.5 times their non-zero row minimums in R (0.5*min)

我對編碼比較陌生,需要幫助將我的數據框中的所有 0 值替換為非零行最小值的 0.5 倍。 例如,我有一個數據框 (df),其中行號代表基因,列代表組織樣本。

> tissue1 <- c(492, 23, 0, 3, 28, 0, 4, 100)
> tissue2 <- c(23, 41, 32, 9, 2, 5, 9, 0)
> tissue3 <- c(56, 1023, 0, 3, 1, 88, 19, 2)
> df <- data.frame(tissue1, tissue2, tissue3)
> print (df)

對於第 6 行(或第 6 行),最小值為 5,5 中的 0.5 為 2.5。 第 6 行中的值在組織 1 中為 2.5,在組織 2 中為 5,在組織 3 中為 88,而不是(分別為 0、5 和 88)。 我想對所有行都這樣做,我的數據框有超過 13000 行和 29 列。

我試圖參考這個尋求幫助-> 用 r 中行的最小值替換 0 值,但這並沒有真正幫助。 我不斷收到警告。

非常感謝任何幫助。 謝謝你。

您還可以使用以下解決方案:

library(dplyr)
library(purrr)

df %>%
  mutate(pmap_dfr(df, ~ ifelse(c(...) == 0, 0.5 * min(c(...)[c(...) != 0]), c(...))))


  tissue1 tissue2 tissue3
1   492.0      23      56
2    23.0      41    1023
3    16.0      32      16
4     3.0       9       3
5    28.0       2       1
6     2.5       5      88
7     4.0       9      19
8   100.0       1       2

base R ,我們可以在將數據集 0 值replace為 NA 后使用pmin來獲取行min ,並在pmin中使用na.rm = TRUE 然后我們用row復制每行的最小值( v1 ),創建一個邏輯矩陣( df==0 )將這些 0 元素分配給相應的行最小值

v1 <-  0.5 * do.call(pmin, c(replace(df, df == 0, NA), na.rm = TRUE))
df[df == 0] <- v1[row(df)[df == 0]]

-輸出

df
#   tissue1 tissue2 tissue3
#1   492.0      23      56
#2    23.0      41    1023
#3    16.0      32      16
#4     3.0       9       3
#5    28.0       2       1
#6     2.5       5      88
#7     4.0       9      19
#8   100.0       1       2

dplyr的做法

library(dplyr)

df %>% mutate(across(everything(), ~ifelse(. == 0, NA, .))) %>%
  rowwise() %>%
  mutate(dummy = min(c_across(everything()), na.rm = T) *0.5) %>%
  ungroup() %>%
  mutate(across(starts_with('tissue'), ~coalesce(., dummy))) %>%
  select(-dummy)

# A tibble: 8 x 3
  tissue1 tissue2 tissue3
    <dbl>   <dbl>   <dbl>
1   492        23      56
2    23        41    1023
3    16        32      16
4     3         9       3
5    28         2       1
6     2.5       5      88
7     4         9      19
8   100         1       2

采用@akrun 的使用replace策略,您可以在這里省去一步

df %>% 
  rowwise() %>%
  mutate(dummy = min(replace(c_across(everything()), c_across(everything()) == 0, NA), na.rm = T) *0.5) %>%
  ungroup() %>%
  mutate(across(starts_with('tissue'), ~ifelse(. == 0, dummy, .))) %>%
  select(-dummy)

# A tibble: 8 x 3
  tissue1 tissue2 tissue3
    <dbl>   <dbl>   <dbl>
1   492        23      56
2    23        41    1023
3    16        32      16
4     3         9       3
5    28         2       1
6     2.5       5      88
7     4         9      19
8   100         1       2

這是否有效:

library(dplyr)
library(tidyr)
df %>% mutate(across(everything(), ~ na_if(., 0))) %>% mutate(id = row_number()) %>% 
   pivot_longer(cols = -id) %>% group_by(id) %>% mutate(value = replace_na(value, min(value, na.rm = TRUE))) %>% 
     pivot_wider(names_from = name, values_from = value) %>% ungroup() %>% select(-id)
# A tibble: 8 x 3
  tissue1 tissue2 tissue3
    <dbl>   <dbl>   <dbl>
1     492      23      56
2      23      41    1023
3      32      32      32
4       3       9       3
5      28       2       1
6       5       5      88
7       4       9      19
8     100       2       2

使用的數據:

df
  tissue1 tissue2 tissue3
1     492      23      56
2      23      41    1023
3       0      32       0
4       3       9       3
5      28       2       1
6       0       5      88
7       4       9      19
8     100       0       2

暫無
暫無

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

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