(我想将一行中的每个元素除以相应的行值。当存在行元素时,分母应为“ Ac”的值。
Ac V1 V2 V3 V4 V5 V6 V7
6.6 NA NA NA NA 0 5.6 5.2
8.4 NA 0 82.5 31 0 0 1.1
Output:
V1 V2 V3 V4 V5 V6 V7
NA 0/8.4 82.5/8.4 31/8.4 (0*6.6+0*6.6)/(6.6+8.4) (5.6*6.6+0*8.4)/(6.6+8.4) (5.2*6.6+1.1*8.4)/(6.6+8.4)
答案 0 :(得分:2)
您的数据:
library(dplyr)
df <- data.frame(V1 = c(rep(NA,4), 0, 5.6, 5.2),
V2 = c(NA, 0 , 82.5, 31, 0, 0, 1.1))
df <- df %>%
t %>% as.data.frame() %>%
dplyr::mutate(Ac = c(6.6, 8.4)) %>%
dplyr::select(Ac, V1:V7)
df
> df
Ac V1 V2 V3 V4 V5 V6 V7
1 6.6 NA NA NA NA 0 5.6 5.2
2 8.4 NA 0 82.5 31 0 0.0 1.1
resp <- df %>%
dplyr::select(-Ac) %>%
t %>% as.data.frame() %>%
dplyr::mutate(V1_1 = V1/df[1,1],
V2_2 = V2/df[2,1]) %>%
dplyr::rowwise() %>%
dplyr::mutate(resp = ifelse(is.na(V1_1) & is.na(V2_2), NA,
sum(V1_1, V2_2, na.rm = T))) %>%
dplyr::select(resp) %>% t %>% as.data.frame()
resp
> resp
V1 V2 V3 V4 V5 V6 V7
resp NA 0 9.821429 3.690476 0 0.8484848 0.9188312
答案 1 :(得分:1)
尝试使用循环并将输出转换为数据框或列表
for (i in 2:8){
temp1 = df[1,i]/df[1,1]
temp2 = df[2,i]/df[2,1]
temp= ifelse(!is.na(temp1)&!is.na(temp2), temp1+temp2,
ifelse(is.na(temp1) &!is.na(temp2), temp2,
ifelse(!is.na(temp1) &is.na(temp2), temp1,NA)))
assign(paste0("V", i-1), temp)
rm(temp1, temp2, temp)
}
output <- c(V1, V2, V3, V4, V5, V6, V7)
output <- data.frame(output)
output
1 NA
2 0.0000000
3 9.8214286
4 3.6904762
5 0.0000000
6 0.8484848
7 0.9188312
答案 2 :(得分:1)
这是tidyverse
的一个选项。我们将除“ Ac”列以外的所有列均除以“ Ac”,然后如果存在任何非NA元素,则summarise_all
返回sum
,否则返回NA
library(tidyverse)
df %>%
transmute_at(-1, list(~ ./Ac)) %>%
summarise_all(list(~ if(all(is.na(.))) NA else sum(.,na.rm = TRUE)))
# V1 V2 V3 V4 V5 V6 V7
#1 NA 0 9.821429 3.690476 0 0.8484848 0.9188312
这也可以一步完成
df %>%
summarise_at(-1, list(~ if(all(is.na(.))) NA else (sum(./Ac, na.rm = TRUE)) ))
# V1 V2 V3 V4 V5 V6 V7
#1 NA 0 9.821429 3.690476 0 0.8484848 0.9188312
基于评论
df %>%
summarise_at(-1, list(~ if(all(is.na(.))) NA
else if(sum(is.na(.)) == 1) (sum(./Ac, na.rm = TRUE))
else (sum(Ac* ., na.rm = TRUE)/sum(Ac, na.rm = TRUE)) ))
# V1 V2 V3 V4 V5 V6 V7
#1 NA 0 9.821429 3.690476 0 2.464 2.904
同样的方法也可以翻译为data.table
library(data.table)
setDT(df)[, lapply(.SD, function(x) if(all(is.na(x))) NA
else sum(x/Ac, na.rm = TRUE)), .SDcols = 2:ncol(df)]
# V1 V2 V3 V4 V5 V6 V7
#1: NA 0 9.821429 3.690476 0 0.8484848 0.9188312
更新的data.table解决方案
setDT(df)[, lapply(.SD, function(x) if(all(is.na(x))) NA
else if(sum(is.na(x)) == 1) (sum(x/Ac, na.rm = TRUE))
else (sum(Ac* x, na.rm = TRUE)/sum(Ac, na.rm = TRUE)) ), .SDcols = 2:ncol(df)]
# V1 V2 V3 V4 V5 V6 V7
#1: NA 0 9.821429 3.690476 0 2.464 2.904
df <- structure(list(Ac = c(6.6, 8.4), V1 = c(NA_real_, NA_real_),
V2 = c(NA, 0), V3 = c(NA, 82.5), V4 = c(NA, 31), V5 = c(0,
0), V6 = c(5.6, 0), V7 = c(5.2, 1.1)), class = "data.frame",
row.names = c(NA,
-2L))
答案 3 :(得分:0)
我们可以将每一行除以该行的第一个值,并按列进行layout_width
sum
如果我们想将第一个元素保留为colSums(df[, -1]/df[[1]], na.rm = TRUE)
# V1 V2 V3 V4 V5 V6 V7
#0.00000 0.00000 9.82143 3.69048 0.00000 0.84848 0.91883
NA