在R中,我有一个数据框如下
J HE JUS HEUS
1 0 0 J-US 0
2 0 0 J-US 0
3 J 0 0 0
4 J 0 0 0
5 0 HE 0 0
6 0 0 0 HE-US
7 0 0 0 0
我想将其缩小为1列,看起来像这样
1 J-US
2 J-US
3 J
4 J
5 HE
6 HE-US
7 0
即。检查每一行并提取非零元素,如果没有非零元素,则使用0.
答案 0 :(得分:2)
这是使用which.max
apply(d, 1, function(x) x[which.max(x != '0')])
# 1 2 3 4 5 6 7
# "J-US" "J-US" "J" "J" "HE" "HE-US" "0"
答案 1 :(得分:1)
或者你可以这样做:
df[cbind(1:nrow(df), max.col(df!=0, "first"))]
#[1] "J-US" "J-US" "J" "J" "HE" "HE-US" "0"
df <- structure(list(J = c("0", "0", "J", "J", "0", "0", "0"), HE = c("0",
"0", "0", "0", "HE", "0", "0"), JUS = c("J-US", "J-US", "0",
"0", "0", "0", "0"), HEUS = c("0", "0", "0", "0", "0", "HE-US",
"0")), .Names = c("J", "HE", "JUS", "HEUS"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7"))
答案 2 :(得分:0)
您可以使用ifelse
检查所有内容是否为0并相应地提取值:
data.frame(x=apply(dat, 1, function(x) ifelse(all(x == "0"), "0", head(x[x!="0"], 1))))
# x
# 1 J-US
# 2 J-US
# 3 J
# 4 J
# 5 HE
# 6 HE-US
# 7 0
答案 3 :(得分:0)
使用粘贴的另一个矢量化选项:
xx <-gsub("0| ","",do.call(paste,dat))
1] "J-US" "J-US" "J" "J" "HE" "HE-US" ""
请注意,如果连续只有零,则会获得空字符。这比“0”更具逻辑性。 如果你想用“0”替换空字符:
xx[nzchar(xx)==0] <- "0"
[1] "J-US" "J-US" "J" "J" "HE" "HE-US" "0"
请注意,即使连续的元素数超过非零,此答案仍然有效。
答案 4 :(得分:0)
另一个矢量化解决方案:
w <- which(dne <- df != 0, arr.ind = TRUE)
unname(ifelse(rowSums(dne), df[w[order(rownames(w)),]], 0))
# [1] "J-US" "J-US" "J" "J" "HE" "HE-US" "0"
或者它可能更容易做到
rs <- unname(rowSums(df != 0))
ifelse(rs != 0, t(df)[t(df) != 0], rs[rs == 0])
# [1] "J-US" "J-US" "J" "J" "HE" "HE-US" "0"