问题
I ran into an R problem, which seems to be a little bit tricky. I have a data.frame that looks like this:
Ident | A1 | ... | An | Z1 | ... | Zn
1 | 1 | ... | 1 | 1 | ... | 0
2 | 6 | ... | 4 | 0 | ... | 1
3 | 4 | ... | 4 | 1 | ... | 0
4 | 1 | ... | 4 | 0 | ... | 0
Now, what I want is to transform the original data.frame to the following structure:
Z | A1 | ... | An
Z1 | 1 | ... | 1
Zn | 6 | ... | 4
Z1 | 4 | ... | 4
Only rows are taken into the resulting data if any of the rows Z's is 1.
Any suggestions? A starting point may be sufficient. Many thanks in advance.
Well here is the dump:
structure(list(Ident = c(1, 2, 3, 4), A1 = c(1, 6, 4, 1), A2 = c(1,
4, 4, 4), Z1 = c(1, 0, 1, 0), Z2 = c(0, 1, 0, 0)), .Names = c("Ident",
"A1", "A2", "Z1", "Z2"), row.names = c(NA, -4L), class = "data.frame")
回答1:
You could write something like
dframe<-dframe[sum(dframe[,zindex1:zindexN])>0,Aindex1:AindexN]
where zindex1:zindexN
is the range of column indices for Z, and similar for Aindex
.
回答2:
Set up data:
edit: add an all-zero row.
dat <- structure(list(Ident = c(1, 2, 3, 4, 5),
A1 = c(1, 6, 4, 1, 2), A2 = c(1, 4, 4, 4, 3),
Z1 = c(1, 0, 1, 1, 0), Z2 = c(0, 1, 0, 0, 0)),
.Names = c("Ident", "A1", "A2", "Z1", "Z2"),
row.names = c(NA, -5L), class = "data.frame")
Find out which columns have the Z elements:
Zcols <- grep("^Z[0-9]+",names(dat))
Pull out their names:
Znames <- names(dat)[Zcols]
Identify the relevant columns and get the appropriate names:
w <- apply(dat[Zcols],1,
function(x) if (all(x==0)) NA else which(x==1))
dd <- data.frame(Z=Znames[w], dat[-Zcols])
If you like you can convert NA
values:
levels(dd$Z) <- c(levels(dd$Z),"missing")
dd$Z[is.na(dd$Z)] <- "missing"
## Z Ident A1 A2
## 1 Z1 1 1 1
## 2 Z2 2 6 4
## 3 Z1 3 4 4
## 4 Z1 4 1 4
## 5 missing 5 2 3
回答3:
Assuming that Ben's answer is what you're looking for (and using his sample data), perhaps you can use melt
and merge
, like this:
library(reshape2)
zCols <- grep("^Z", names(dat), value = TRUE) ## Just the Z cols
otherCols <- setdiff(names(dat), zCols) ## The other columns
datL <- melt(dat, measure.vars = zCols) ## melting
merge(dat[otherCols], ## merging
datL[as.logical(datL$value), c(otherCols, "variable")],
all = TRUE)
# Ident A1 A2 variable
# 1 1 1 1 Z1
# 2 2 6 4 Z2
# 3 3 4 4 Z1
# 4 4 1 4 Z1
# 5 5 2 3 <NA>
来源:https://stackoverflow.com/questions/16232192/switch-column-to-row-in-a-data-frame