我试图比较R中的两个时间序列,通过在线图上绘制它们来评估它们的相关程度。为了避免为数据分别设置两个轴,我想对每个值进行索引,通过绘制索引而不是原始数据来绘制自日期X以来值的变化。
数据如下所示:
Table 1.
Month A B
Jan 3883 151831
Feb 3626 154070
Mar 4346 163550
Apr 3439 155674
所需的输出如下所示:
Table 2.
Month A A.index B B.index
Jan 3883 100 151831 100
Feb 3626 93.38 154070 101.47
Mar 4346 111.92 163550 107.71
Apr 3439 88.56 155674 102.53
我可以通过将表1导出到excel并为A.index和B.index添加一列并使用计算来确定索引号为100的变化来实现excel。假设A在B列中,然后我简单地说:
=(cn)/c$2*100
其中cn是C列第n行,c $ 2是原始值,100是索引号。
但是,我想知道如何在R中实现相同的功能,这样我就可以将它包装在一个函数中,因为这将是我需要半定期完成的事情。
干杯汤姆
答案 0 :(得分:4)
使用tranform()
,这很简单。关键线实际上与Excel代码非常相似,应该是不言自明的。
df <- read.table(text="Month A B
Jan 3883 151831
Feb 3626 154070
Mar 4346 163550
Apr 3439 155674", header=T)
df <- transform(df, A.index=100*A/A[1], B.index=100*B/B[1])
df
# Month A B A.index B.index
# 1 Jan 3883 151831 100.00000 100.0000
# 2 Feb 3626 154070 93.38141 101.4747
# 3 Mar 4346 163550 111.92377 107.7185
# 4 Apr 3439 155674 88.56554 102.5311
答案 1 :(得分:2)
可能更具伸缩性/通用的解决方案是使用apply()
函数迭代所有列,无论您拥有多少列:
x <- matrix(c(3883, 151831, 3626, 154070, 4346, 163550, 3439, 155674),
ncol = 2, byrow = TRUE, dimnames = list(NULL, c("A", "B")))
apply(x, 2, function(y) 100 * y / y[1])
A B
[1,] 100.00000 100.0000
[2,] 93.38141 101.4747
[3,] 111.92377 107.7185
[4,] 88.56554 102.5311
如果需要,您显然可以cbind()
将此信息恢复为原始数据,或者直接将其绘制出来。
答案 2 :(得分:0)
您还可以使用public class MainActivity extends AppCompatActivity {
TextView reg;
EditText email,password;
Button loginBt;
Database db;
String emailString,passwordString;
TextView regText;
TextView name,code;
private DatabaseReference ref;
@Override
protected void onCreate(Bundle savedInstanceState) {
ref = FirebaseDatabase.getInstance().getReference().child("Hospital").child("ABA");
db = new Database();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
email = (EditText) findViewById(R.id.logInEmail);
password = (EditText) findViewById(R.id.passwordLogin);
regText = (TextView) findViewById(R.id.reg_text);
loginBt = (Button) findViewById(R.id.logInButton);
/* loginBt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
login();
}
});*/
regText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createAccount();
}
});
name = (TextView) findViewById(R.id.hospitalNameMain);
code = (TextView) findViewById(R.id.hospitalCodeMain);
loginBt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
show();
}
});
}
private void show() {
ref = FirebaseDatabase.getInstance().getReference().child("Hospital").child("QCH");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Toast.makeText(MainActivity.this,"log in ",Toast.LENGTH_SHORT).show();
String hospitalName = dataSnapshot.child("hospital_name").getValue().toString();
String hospitalCode = dataSnapshot.child("hospital_code").getValue().toString();
name.setText(hospitalName);
code.setText(hospitalCode);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void createAccount() {
Intent i = new Intent(this, RegistrationActivity.class);
startActivity(i);
}
}
函数,该函数与sweep
类似,并且在时间序列上也很好用
apply
如果df不是时间序列,而是data.frame必须放置df <- ts(data = data.frame(A = c(3883, 3626, 4346, 3439),
B = c(151831,154070, 163550, 155674)),
frequency = 12)
sweep(df, MARGIN = 2, STATS = df[1,], FUN = "/") * 100
A B
Jan 1 100.00000 100.0000
Feb 1 93.38141 101.4747
Mar 1 111.92377 107.7185
Apr 1 88.56554 102.5311
,否则将返回错误。